SQL BillingState!= CA
Я был на этом в течение нескольких часов и у меня проблемы с логикой.
Вопрос задает вопрос: найдите плейлист, в котором есть один или несколько треков, которые никогда не были куплены в Калифорнии (Калифорния). Распечатайте Id и название таких плейлистов.
Наборы отношений можно найти здесь:
https://chinookdatabase.codeplex.com/wikipage?title=Chinook_Schema&referringTitle=Documentation
Мои решения ничего не возвращают, и я прав или нет, понятия не имею. Если мое решение неверно, где ошибка в моей логике? И если это неправильно, то как правильно подходить к этой проблеме (решение будет предпочтительнее с объяснением)
Мое решение:
Select DISTINCT P.PlaylistId, P.Name, I.BillingState
From Playlist P, Invoice I, Track T
Where P.PlaylistId IN (
Select PT.PlaylistId
From PlaylistTrack PT
Where PT.TrackId IN(
Select T.TrackId
From Track T
Where T.TrackId IN(
Select IL.InvoiceLineId
From InvoiceLine IL
Where IL.InvoiceId IN(
Select I.InvoiceId
FROM Invoice I
WHERE I.BillingState = 'CA'
Group by I.InvoiceId
Having COUNT(I.InvoiceId) < 1))))
Group By T.TrackId
HAVING COUNT (T.TrackId) > 1
2 ответа
Позвольте мне объяснить, почему ваш код не работает. (У Даррена вполне разумный ответ.)
Select I.InvoiceId
FROM Invoice I
WHERE I.BillingState = 'CA'
Group by I.InvoiceId
Having COUNT(I.InvoiceId) < 1
Этот подзапрос логически некорректен. Он всегда вернет пустой набор. Зачем? Вы ограничиваете счета для тех, которые имеют CA
, Следовательно, каждый счет будет иметь по крайней мере одну строку перед GROUP BY
, Следовательно HAVING
предложение отфильтрует все.
Вы хотите условную агрегацию:
Select I.InvoiceId
FROM Invoice I
Group by I.InvoiceId
Having SUM(CASE WHEN I.BillingState = 'CA' THEN 1 ELSE 0 END) = 0;
Но вам, вероятно, не нужно агрегировать по InvoiceId
, Это должно быть уникальным. Итак, как насчет:
SELECT I.InvoiceId
FROM Invoice I
WHERE I.BillingState <> 'CA'
Я бы использовал JOIN
,
SELECT PlayListId, Name
FROM PlayList PL
INNER JOIN PlayerListTrack PLT ON PLT.PlayListId = PL.PlayListId
INNER JOIN Track T ON T.Trackid = PLT.TrackId
INNER JOIN InvoiceLine IL ON IL.TrackId = T.TrackID
INNER JOIN Invoice I ON I.InvoiceId = IL.InvoiceId
WHERE I.BillingState != 'CA'
Это объединяет все таблицы соответственно и отфильтровывает таблицу счетов-фактур (столбец BillingState), где значения не равны Калифорнии.