web-dev-qa-db-fra.com

L'identifiant en plusieurs parties n'a pas pu être lié

J'ai vu des erreurs similaires sur SO, mais je ne trouve pas de solution à mon problème .J'ai une requête SQL comme:

SELECT DISTINCT
        a.maxa ,
        b.mahuyen ,
        a.tenxa ,
        b.tenhuyen ,
        ISNULL(dkcd.tong, 0) AS tongdkcd
FROM    phuongxa a ,
        quanhuyen b
        LEFT OUTER JOIN ( SELECT    maxa ,
                                    COUNT(*) AS tong
                          FROM      khaosat
                          WHERE     CONVERT(DATETIME, ngaylap, 103) BETWEEN 'Sep 1 2011'
                                                              AND
                                                              'Sep 5 2011'
                          GROUP BY  maxa
                        ) AS dkcd ON dkcd.maxa = a.maxa
WHERE   a.maxa <> '99'
        AND LEFT(a.maxa, 2) = b.mahuyen
ORDER BY maxa;

Lorsque j'exécute cette requête, le résultat de l'erreur est le suivant: L'identificateur en plusieurs parties "a.maxa" ne peut pas être lié. Pourquoi?
P/s: si je divise la requête en 2 requête individuelle, elle fonctionne correctement.

SELECT DISTINCT
        a.maxa ,
        b.mahuyen ,
        a.tenxa ,
        b.tenhuyen
FROM    phuongxa a ,
        quanhuyen b
WHERE   a.maxa <> '99'
        AND LEFT(a.maxa, 2) = b.mahuyen
ORDER BY maxa;

et

SELECT  maxa ,
        COUNT(*) AS tong
FROM    khaosat
WHERE   CONVERT(DATETIME, ngaylap, 103) BETWEEN 'Sep 1 2011'
                                        AND     'Sep 5 2011'
GROUP BY maxa;
162
PhamMinh

Vous mélangez des jointures implicites avec des jointures explicites. Cela est autorisé, mais vous devez savoir comment le faire correctement.

Le fait est que les jointures explicites (celles qui sont implémentées à l'aide du mot clé JOIN) ont priorité sur les jointures implicites (les jointures 'virgule', où la condition de jointure est spécifiée dans la clause WHERE.

Voici un aperçu de votre requête:

SELECT
  …
FROM a, b LEFT JOIN dkcd ON …
WHERE …

Vous vous attendez probablement à ce qu'il se comporte comme ceci:

SELECT
  …
FROM (a, b) LEFT JOIN dkcd ON …
WHERE …

c'est-à-dire que la combinaison des tables a et b est jointe à la table dkcd. En fait, ce qui se passe est

SELECT
  …
FROM a, (b LEFT JOIN dkcd ON …)
WHERE …

c'est-à-dire que, comme vous l'avez peut-être déjà compris, dkcd est associé spécifiquement à b et à uniquement b, le résultat de la jointure est alors combiné à a et filtré avec la clause WHERE. Dans ce cas, toute référence à a dans la clause ON est invalide, a est inconnue à ce stade. C'est pourquoi vous obtenez le message d'erreur.

Si j'étais vous, j'essaierais probablement de réécrire cette requête, et une solution possible pourrait être:

SELECT DISTINCT
  a.maxa,
  b.mahuyen,
  a.tenxa,
  b.tenhuyen,
  ISNULL(dkcd.tong, 0) AS tongdkcd
FROM phuongxa a
  INNER JOIN quanhuyen b ON LEFT(a.maxa, 2) = b.mahuyen
  LEFT OUTER JOIN (
    SELECT
      maxa,
      COUNT(*) AS tong
    FROM khaosat
    WHERE CONVERT(datetime, ngaylap, 103) BETWEEN 'Sep 1 2011' AND 'Sep 5 2011'
    GROUP BY maxa
  ) AS dkcd ON dkcd.maxa = a.maxa
WHERE a.maxa <> '99'
ORDER BY a.maxa

Ici, les tables a et b sont jointes en premier, puis le résultat est joint à dkcd. Fondamentalement, il s'agit de la même requête que la vôtre, n'utilisant qu'une syntaxe différente pour l'une des jointures, ce qui fait une grande différence: la référence a.maxa dans la condition de jointure de la variable dkcd est maintenant absolument valide.

Comme @Aaron Bertrand l'a bien noté, vous devriez probablement qualifier maxa avec un alias spécifique, probablement a, dans la clause ORDER BY.

188
Andriy M

Parfois, cette erreur se produit lorsque vous utilisez votre schéma (dbo) dans votre requête de manière incorrecte.

par exemple si vous écrivez:

select dbo.prd.name
from dbo.product prd

vous obtiendrez l'erreur.

Dans ces situations, changez le en:

select prd.name
from dbo.product prd
34
Bobs

si vous avez donné le nom de votre ali, changez-le en 

par exemple

SELECT  
    A.name,A.date
  FROM [LoginInfo].[dbo].[TableA] as A
   join 
  [LoginInfo].[dbo].[TableA] as B 
  on  [LoginInfo].[dbo].[TableA].name=[LoginInfo].[dbo].[TableB].name;

changer cela en 

SELECT  
    A.name,A.date
  FROM [LoginInfo].[dbo].[TableA] as A
   join 
  [LoginInfo].[dbo].[TableA] as B 
  on  A.name=B.name;
9

Je me débattais avec le même message d'erreur dans SQL SERVER, car j'avais plusieurs jointures. Changer le ordre des jointures l'a résolu pour moi.

7
Pavel M.

Dans mon cas, le problème s’est avéré être le pseudonyme que j’avais donné à la table. "oa" semble ne pas être acceptable pour SQL Server.

2
Hashim Akhtar

Si cette erreur se produit dans une UPDATE, revérifiez la JOIN dans la table avec la colonne/le champ à l'origine de l'erreur.

Dans mon cas, cela était dû à l'absence de la variable JOIN elle-même, qui générait la même erreur en raison d'un champ inconnu (comme Andriy a souligné ).

1
CPHPython

Avez-vous oublié de rejoindre certaines tables? Sinon, vous devrez probablement utiliser certains alias.

1
JedatKinports
SELECT DISTINCT
        phuongxa.maxa ,
        quanhuyen.mahuyen ,
        phuongxa.tenxa ,
        quanhuyen.tenhuyen ,
        ISNULL(dkcd.tong, 0) AS tongdkcd
FROM    phuongxa ,
        quanhuyen
        LEFT OUTER JOIN ( SELECT    khaosat.maxa ,
                                    COUNT(*) AS tong
                          FROM      khaosat
                          WHERE     CONVERT(DATETIME, ngaylap, 103) BETWEEN 'Sep 1 2011'
                                                              AND
                                                              'Sep 5 2011'
                          GROUP BY  khaosat.maxa
                        ) AS dkcd ON dkcd.maxa = maxa
WHERE   phuongxa.maxa <> '99'
        AND LEFT(phuongxa.maxa, 2) = quanhuyen.mahuyen
ORDER BY maxa;
1
SVaidya

Je connais bien SQL, mais je suis tombé sur ce problème dans un cours que je suivais et j'ai constaté qu'assigner la requête au projet avait permis d'éliminer spécifiquement l'erreur en plusieurs parties. Par exemple, le projet que j'ai créé était CTU SQL Project. Je me suis donc assuré de démarrer mon script avec USE [CTU SQL Project] comme première ligne, comme ci-dessous.

USE [CTU SQL Project]
SELECT Advisors.First_Name, Advisors.Last_Name...and so on.
1
Bogartz

Au lieu de cela, vous pouvez essayer de joindre des tables comme,

select 
  .... 
from 
   dkcd 
     right join 
                a
                  , b

Cela devrait marcher

1
Suman Kumar

Mon erreur était d'utiliser un champ qui n'existait pas dans la table.

table1.field1 => n'existe pas

table2.field1 => est correct

Corrigez votre nom de table.

mon erreur est due à l'utilisation de WITH

WITH RCTE AS (
   SELECT...
)
SELECT RCTE.Name, ...
FROM 
  RCTE INNER JOIN Customer
  ON RCTE.CustomerID = Customer.ID 

lorsqu'il est utilisé en jointure avec d'autres tables ...

1
Zolfaghari

J'avais la même erreur de JDBC. Vérifié tout et ma requête était bien. En fait, dans la clause où j'ai un argument:

where s.some_column = ?

Et la valeur de l'argument que je transmettais était nulle. Cela donne également la même erreur, ce qui est trompeur, car lorsque vous effectuez une recherche sur Internet, vous vous rendez compte que quelque chose ne va pas avec la structure de la requête mais ce n'est pas dans mon cas. Juste pensé que quelqu'un pourrait faire face au même problème

1
xbmono

Ce qui a fonctionné pour moi a été de changer ma clause WHERE en une sous-requête SELECT

DE:

    DELETE FROM CommentTag WHERE [dbo].CommentTag.NoteId = [dbo].FetchedTagTransferData.IssueId

À:

    DELETE FROM CommentTag WHERE [dbo].CommentTag.NoteId = (SELECT NoteId FROM FetchedTagTransferData)
0
SauerTrout

J'étais également aux prises avec cette erreur et je me suis retrouvé avec la même stratégie que la réponse. J'inclus ma réponse juste pour confirmer qu'il s'agit d'une stratégie qui devrait fonctionner. 

Voici un exemple où je fais d’abord une jointure interne entre deux tables dont je sais qu’elles ont des données, puis deux jointures externes de gauche sur des tables pouvant contenir des lignes correspondantes pouvant être vides. Vous mélangez des jointures internes et des jointures externes pour obtenir des résultats avec des données sur plusieurs tables au lieu d'utiliser la syntaxe par défaut, séparée par des virgules, entre les tables et de rater des lignes dans la jointure souhaitée. 

use somedatabase
go 

select o.operationid, o.operatingdate, p.pasid, p.name as patientname, o.operationalunitid, f.name as operasjonsprogram,  o.theaterid as stueid, t.name as stuenavn, o.status as operasjonsstatus from operation o 
inner join patient p on o.operationid = p.operationid 
left outer join freshorganizationalunit f on f.freshorganizationalunitid = o.operationalunitid
left outer join theater t on t.theaterid = o.theaterid
where (p.Name like '%Male[0-9]%' or p.Name like '%KFemale [0-9]%')

Premièrement: effectuez les jointures internes entre les tables pour lesquelles vous souhaitez que les données correspondent. Deuxième partie: continuez avec les jointures externes pour essayer de récupérer des données dans d'autres tables, mais ceci ne filtrera pas votre jeu de résultats si la jointure externe de table à n'a pas obtenu les données correspondantes ou ne correspond pas à la condition que vous avez définie dans le prédicat/condition on.

0
Tore Aurstad