2010-07-12 2 views
0

Возможно ли сделать CROSS JOIN между двумя таблицами, за которым следует LEFT JOIN на третьей таблице, а затем, возможно, больше левых объединений? Я использую SQL Server 2000/2005.Cross Join, а затем Left Join

У меня есть следующий запрос, который довольно прямойForForMO IMO, но я получаю сообщение об ошибке.

select P.PeriodID, 
     P.PeriodQuarter, 
     P.PeriodYear, 
     M.Name, 
     M.AuditTypeId, 
     A.AuditId 
from Period P, Member M 

LEFT JOIN Audits A 
ON P.PeriodId = A.PeriodId 

WHERE 
    P.PeriodID > 29 AND P.PeriodID < 38 
    AND M.AuditTypeId in (1,2,3,4) 
order by M.Name 

Я получаю следующее сообщение об ошибке:

Msg 4104, Level 16, State 1, Line 1 The multi-part identifier "P.PeriodId" could not be bound.

Если удалить LEFT JOIN, запрос работает. Тем не менее, мне нужен LEFT JOIN, так как есть больше информации, которую мне нужно извлечь из других таблиц.

Что я делаю неправильно? Есть ли лучший способ этого?

ответ

1

Вы не можете комбинировать явные и неявные присоединяется - see this running example.

CROSS JOINs должно быть так редко использоваться в системе, что я хочу, чтобы каждый из них был явным, чтобы убедиться, что это явно не ошибка кодирования или ошибка дизайна.

Если вы хотите, чтобы сделать неявное левое внешнее соединение, сделать это (не поддерживается в SQL Azure):

select P.PeriodID, 
     P.PeriodQuarter, 
     P.PeriodYear, 
     M.Name, 
     M.AuditTypeId, 
     A.AuditId 
from #Period P, #Member M, #Audits A 
WHERE 
    P.PeriodID > 29 AND P.PeriodID < 38 
    AND M.AuditTypeId in (1,2,3,4) 
    AND P.PeriodId *= A.PeriodId 
order by M.Name​ 
+0

Thnx. Это делает меня понятнее. Выполнение перекрестного соединения - единственный способ, который я могу решить, чтобы решить мою конкретную проблему. Что делает оператор «* =»? –

+0

@Saajid Imsail * = это старый оператор LEFT JOIN для неявных объединений. –

+0

Этот оператор ненадежный и устаревший, правильное исправление заключается в использовании явных объединений. Нет никакого оправдания для того, чтобы не использовать явные объединения в любом запросе. – HLGEM

5

Вы забыли CROSS JOIN в запросе:

select P.PeriodID, 
     P.PeriodQuarter, 
     P.PeriodYear, 
     M.Name, 
     M.AuditTypeId, 
     A.AuditId 
from Period P CROSS JOIN Member M 

LEFT JOIN Audits A 
ON P.PeriodId = A.PeriodId 

WHERE 
    P.PeriodID > 29 AND P.PeriodID < 38 
    AND M.AuditTypeId in (1,2,3,4) 
order by M.Name 
+0

мне не нужно указывать его, AFAIK. Запрос работает нормально, если я удаляю LEFT JOIN в таблицу Audits. Из того, что я прочитал, мой ОП определяет неявное перекрестное соединение. –

+0

ОК, поэтому я попробовал ваш код, и теперь он работает. Но почему? Это не имеет смысла. –

+0

@Saajid: SQL Устанавливает сразу все предложения. Например, вы не можете указывать 'select a + b как c, 2 * c как double_c' Потому что' c' не определяется при запуске предложения select. То же самое происходит при смешивании старого и нового стилей. Кусочки между запятыми в предложении from каждый смотрят, как будто в parellel. Таким образом, значение Р, определенное на левой стороне запятой, не видно справа. См. Http://stackoverflow.com/questions/1080097/the-multi-part-identifier-could-not-be-bound-on-sql-server-2005-8/1080407#1080407 для другого примера. –

Смежные вопросы