Идентификатор с несколькими частями не может быть связан

Я видел подобные ошибки в SO, но я не нашел решения для своей проблемы. У меня есть SQL-запрос вроде:

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;

Когда я выполняю этот запрос, результат ошибки: Идентификатор с несколькими частями "a.maxa" не может быть связан. Почему?
P/s: если я делю запрос на 2 отдельных запроса, он работает нормально.

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;

и

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

Ответ 1

Вы смешиваете неявные соединения с явным соединением. Это разрешено, но вам нужно знать, как это сделать должным образом.

Дело в том, что явные объединения (те, которые реализованы с использованием ключевого слова JOIN) имеют приоритет над неявными (объединение "comma", где условие соединения указано в предложении WHERE).

Вот схема вашего запроса:

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

Вероятно, вы ожидаете, что он будет вести себя следующим образом:

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

то есть комбинация таблиц a и b соединяется с таблицей dkcd. На самом деле, что происходит

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

то есть, как вы уже поняли, dkcd соединен специально с b и только b, тогда результат объединения объединяется с a и далее фильтруется с предложением WHERE, В этом случае любая ссылка на a в предложении ON недействительна, a неизвестно в этой точке. Вот почему вы получаете сообщение об ошибке.

Если бы я был вами, я бы, вероятно, попытался переписать этот запрос, и одним из возможных решений могло бы быть:

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

Здесь сначала соединяются таблицы a и b, затем результат соединяется с dkcd. В основном, это тот же запрос, что и ваш, только с использованием другого синтаксиса для одного из соединений, что имеет большое значение: ссылка a.maxa в состоянии соединения dkcd теперь абсолютно корректна.

Как правильно отметил @Aaron Bertrand, вы должны, вероятно, квалифицировать maxa с определенным псевдонимом, возможно a, в предложении ORDER BY.

Ответ 2

Иногда эта ошибка возникает, когда вы неправильно используете свою схему (dbo) в своем запросе.

например, если вы пишете:

select dbo.prd.name
from dbo.product prd

вы получите сообщение об ошибке.

В таких ситуациях измените его на:

select prd.name
from dbo.product prd

Ответ 3

если вы указали имя имени слияния, которое соответствует фактическому имени

для ex.

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;

измените это на

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

Ответ 4

Я новичок в SQL, но столкнулся с этой проблемой в курсе, который я принимал, и обнаружил, что назначение запроса проекту специально помогло устранить многочастную ошибку. Например, проект, который я создал, был CTU SQL Project, поэтому я убедился, что начал свой script с USE [CTU SQL Project] в качестве первой строки, как показано ниже.

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

Ответ 5

Я работал с тем же сообщением об ошибке в SQL SERVER, так как у меня было несколько объединений, изменение порядка соединений разрешило это для меня.

Ответ 6

Если эта ошибка происходит в UPDATE, дважды проверьте JOIN в таблице с полем столбца /, вызывающим ошибку.

В моем случае это было связано с отсутствием самого JOIN, который породил ту же ошибку из-за неизвестного поля (как Андрей указал).

Ответ 7

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;

Ответ 8

Моя ошибка состояла в том, чтобы использовать поле, которое не было в таблице.

table1.field1 = > не существует

table2.field1 = > правильный

Исправить имя таблицы.

моя ошибка произошла из-за использования WITH

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

при использовании в соединении с другими таблицами...

Ответ 9

Вместо этого вы можете попробовать подключиться к таблицам, например,

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

Это должно работать