2013-02-01 11 views
10

Schema:Identyfikator wieloczęściowy nie mógł być związany - podzapytanie

create table TableA (A1 int) 
create table TableB (B1 int, B2 int) 
create table TableC (C1 int) 

zapytania Problematyczne:

SELECT * 
FROM TableA a 
INNER JOIN TableB b ON b.B1=a.A1 
INNER JOIN (SELECT TOP 1 * 
      FROM TableC c 
      WHERE c.C1=b.B1 ORDER BY c.C1) d ON d.C2=b.B2 
INNER JOIN OtherTable ON OtherTable.Foo=d.C1 

Budowanie tego schematu i uruchomienie kwerendy w SQLFiddle pod SQL Server 2008 wyniki w:

The multi-part identifier "b.B1" could not be bound.: SELECT * FROM TableA a INNER JOIN TableB b ON b.B1=a.A1 INNER JOIN (SELECT TOP 1 * FROM TableC c WHERE c.C1=b.B1 ORDER BY c.C1) d ON d.C2=b.B2 

Korzystanie CROSS APPLY zamiast INNER JOIN do poprawek podzapytaniu problem

Na czym polega problem?

Edytuj: Dodałem "TOP 1", który był częścią prawdziwego zapytania i jest istotną częścią problemu.

Edycja2: Więcej informacji na temat problemu.

+0

OK. Spójrz na swoje podkwerendy. Filtrujesz według C1, a następnie ORDER BY C1. Co to znaczy? Myślę, że musisz "ZAMAWIĆ PRZEZ" C2. –

+0

To jest abstrakcja prawdziwego zapytania –

+0

Ale zakłócasz logikę. Zobacz moją zaktualizowaną odpowiedź. –

Odpowiedz

2

nie można odwołać z JOIN klauzuli do innej części PRZYSTĄPIĆ.

Użyj tego zamiast.

SELECT * 
FROM TableA a 
INNER JOIN TableB b 
    ON b.B1=a.A1 
INNER JOIN TableC c 
    ON d.C2=b.B2 
     AND c.C1=b.B1 

EDITED

SELECT * 
FROM TableA a 
INNER JOIN TableB b ON b.B1=a.A1 
WHERE b.B2 = (SELECT TOP 1 c.C2 
       FROM TableC c 
       WHERE c.C1=b.B1 ORDER BY c.C1) 

dalszego stosowania TableC w JOIN-ów można to wykorzystać.

SELECT * 
FROM TableA a 
    INNER JOIN TableB b 
     ON b.B1=a.A1 
    INNER JOIN 
     (
      SELECT 
       ROW_NUMBER() OVER (PARTITION BY C1 ORDER BY C2) RN, 
       C2 
       --, other columns fromTableC if needed 
      FROM TableC 
     ) CC 
    ON b.B2 = CC.C2 
     AND CC.RN = 1 
+0

Co się stanie, jeśli "SELECT TOP 1" będzie potrzebny w dalszych wewnętrznych połączeniach? –

+0

Używanie "ROW_NUMBER()" jest przestępstwem. –

+1

'Używanie" ROW_NUMBER() "jest przestępstwem." Dlaczego? –

3

Nie można uzyskać dostępu do aliasu z łączenia wewnątrz innego połączonego podkwerendy. Trzeba będzie użyć następujących która łączy podzapytania na dwóch kolumnach/Stoły:

SELECT * 
FROM TableA a 
INNER JOIN TableB b 
    ON b.B1=a.A1 
INNER JOIN 
(
    SELECT * 
    FROM TableC c 
) d 
    ON d.C2=b.B2 
    AND d.C1 = b.B1 

Albo można to zapisać jako:

SELECT * 
FROM TableA a 
INNER JOIN TableB b 
    ON b.B1=a.A1 
INNER JOIN TableC c 
    ON c.C2=b.B2 
    AND c.C1 = b.B1 
+2

'Nie można uzyskać dostępu do aliasu wewnątrz podzapytania." Nie sądzę. 'SELECT * FROM Table1 T1 WHERE someColumn IN (SELECT someColumn FROM Table2 WHERE T1.Id = Table1_dd)' –

+1

@HamletHakobyan naprawiony – Taryn

+0

Edytowałem moje pytanie. –

Powiązane problemy