2013-02-01 3 views
10

Schéma:L'identifiant plusieurs parties ne pouvait pas être lié - sous-requête

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

requête Problématiques:

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 

La construction de ce schéma et d'exécuter la requête dans SQLFiddle sous SQL Server 2008 les résultats dans:

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 

en utilisant au lieu de CROSS APPLIQUER INNER JOIN pour les corrections de sous-requête l'issue

Quel est le problème? Edit: J'ai ajouté "TOP 1" qui faisait partie de la requête réelle et c'est une partie pertinente du problème.

Édition2: Informations supplémentaires sur le problème.

+0

OK. Regardez votre sous-requête. Vous filtrez par C1 puis ORDER BY C1. Quel est le sens? Je pense que vous devez «ORDER BY» C2. –

+0

Ceci est une abstraction de la vraie requête –

+0

Mais vous déformez la logique. Voir ma réponse mise à jour. –

Répondre

2

vous ne pouvez pas faire référence de JOIN clause à une autre partie JOINDRE.

Utilisez ceci à la place.

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 

ÉDITÉ

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) 

Pour une utilisation ultérieure de TableC en vous pouvez JOIN-s utiliser.

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

Que faire si le "SELECT TOP 1" est nécessaire dans d'autres jointures internes? –

+0

L'utilisation de "ROW_NUMBER()" est criminelle. –

+1

'Utiliser" ROW_NUMBER() "est criminel." Pourquoi? –

3

Vous ne pouvez pas accéder à un alias à partir d'une jointure à l'intérieur d'une autre sous-requête jointe. Vous aurez besoin d'utiliser les éléments suivants qui se joint à la sous-requête sur deux colonnes/tables:

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 

Ou cela peut être écrit:

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

'Vous ne pouvez pas accéder à un alias à l'intérieur d'une sous-requête. Je ne le pense pas. 'SELECT * FROM Table1 T1 O some someColumn IN (SELECT someColumn FROM Table2 O WH T1.Id = Table1_Id)' –

+1

@HamletHakobyan corrigé – Taryn

+0

J'ai édité ma question. –

Questions connexes