Я'видел подобные ошибки на 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;
Вы смешиваете неявные соединения с явными соединениями. Это допустимо, но вы должны знать, как правильно это делать.
Дело в том, что явные объединения (те, которые реализуются с помощью ключевого слова JOIN
) имеют приоритет над неявными (объединения 'через запятую', где условие объединения указано в предложении 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
.
Иногда эта ошибка возникает, когда вы неправильно используете схему (dbo) в запросе.
Например, если вы напишете:
select dbo.prd.name
from dbo.product prd
вы получите ошибку.
В этой ситуации измените его на:
select prd.name
from dbo.product prd
если вы дали Алесь изменить имя на реальное имя
например
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;
В моем случае проблема оказалась псевдоним, который я дал к столу. на "ОА" по-видимому, не приемлемо для SQL-сервера.
У меня была такая же ошибка из JDBC. Проверил все, и мой запрос был в порядке. Оказалось, в предложении where, у меня есть аргумент:
where s.some_column = ?
И значение аргумента я проходил в нуль. Это также дает ту же ошибку, которая вводит в заблуждение, потому что, когда вы будете искать в интернете вы в конечном итоге что-то не так со структурой запроса, но это's не в моем случае. Просто думал, что кто-то может столкнуться с такой же проблемой
Что работал для меня, чтобы изменить мое предложение where в подзапросе выбрать
От:
DELETE FROM CommentTag WHERE [dbo].CommentTag.NoteId = [dbo].FetchedTagTransferData.IssueId
К:
DELETE FROM CommentTag WHERE [dbo].CommentTag.NoteId = (SELECT NoteId FROM FetchedTagTransferData)
Я новичок в SQL, но столкнулся с этой проблемой на курсе, который я прохожу, и обнаружил, что назначение запроса конкретно проекту помогает устранить ошибку с несколькими частями. Например, проект, который я создал, был CTU SQL Project, поэтому я убедился, что начал свой сценарий с USE [CTU SQL Project] в качестве первой строки, как показано ниже.
USE [CTU SQL Project]
SELECT Advisors.First_Name, Advisors.Last_Name...and so on.
Моя ошибка была использовать поле, которое не существует в таблице.
таблица1.поле1 => не существует
таблица2.поле1 => есть правильно
Правильное имя таблицы.
моя ошибка произошла из-за использования с
WITH RCTE AS (
SELECT...
)
SELECT RCTE.Name, ...
FROM
RCTE INNER JOIN Customer
ON RCTE.CustomerID = Customer.ID
когда используется при соединении с другими таблицами ...
Вместо этого вы можете попробовать соединение таблиц, как,
select
....
from
dkcd
right join
a
, b
Это должно работать
Я также боролся с этой ошибкой и в конечном итоге с той же стратегии, как и ответ. Я отвечу просто чтобы убедиться, что это стратегия, которая должна работать.
Вот пример, где я делаю сначала одно внутреннее соединение между двумя таблицами, я знаю, что есть данные, а затем две левые внешние соединения таблиц, которые могут иметь соответствующие строки, Что может быть пустым. Вы смешиваете внутренних соединений и внешних соединений, чтобы получить результаты с через таблицы данных, вместо того, чтобы делать запятая по умолчанию разделенных синтаксис между столами и пропустить строки в нужном вам присоединиться.
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]%')
Первый: выполнить внутренние соединения между таблицами вы планируете иметь соответствующие данные. Вторая часть: Продолжение с внешних соединений, чтобы попытаться извлечь данные в других таблицах, но это не отфильтровать результирующий набор, если таблица внешние присоединения, не получил соответствующие данные и матч при условии, что вы настроили в предикате / состояние.
Если эта ошибка происходит в "обновить" перепроверить "регистрация" на стол столбец/поле, которое вызывает ошибку.
В моем случае это было из-за отсутствия "присоединиться", которая генерируется та же ошибка из-за неизвестной поля (как Андрей указал).
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;