мислити з точки зору множин, а не ітераторів; оператори sql визначають властивості потрібного набору вихідних даних (він же таблиця / відношення)
всі імена місця, такі, що для кожного гуртуКонтарт є група з тієї країни, яка грає на місці цього імені
Результатом цього (якщо я правильно зрозумів ваші наміри!) буде набір місць, що мають принаймні одну групу, яка грає в цьому місці. Ітерація над bandCountry непотрібна, оскільки відношення PLAYS вже містить інформацію, яку ви шукаєте, вам просто потрібно усунути дублікати
тож у SQL це було б:
select
distinct venueName
from PLAYS
РЕДАКТУВАТИ: нормально, тому бажаний фактичний набір трохи складніше. База даних запитує: на яких майданчиках розміщуються групи з усіх країн?
Отже, ми визначаємо критерії членства для елемента бажаного набору як мети, а потім працюємо назад, щоб заповнити набір. Місце проведення є членом набору результатів, якщо він має рядок PLAYS щонайменше для одного діапазону з кожної країни. Як ми отримуємо цю інформацію?
Один із способів - підрахувати різні країни для кожного місця і порівняти їх з кількістю всіх країн. Але ми не маємо відношення до КРАЇНИ. Якщо ми замислимось над моделлю, заданою на мить, ми бачимо, що набір усіх країн не є правильними критеріями; це безліч усіх країн, що мають принаймні одну смугу. Таким чином, нам не потрібна таблиця країни (хоча для нормалізованої моделі у нас вона повинна бути), і нам не байдуже країну місця проведення, ми можемо просто порахувати країни, у яких є групи, наприклад (у MS-SQL )
declare @BandCountryCount int
select
@BandCountryCount = COUNT(distinct bandCountry)
from BAND
Ми можемо порахувати країни гурту для кожного місця
select
P.venueName, COUNT(distinct B.bandCountry) as VenueBandCountryCount
from PLAYS P
inner join BAND B on B.bandName = P.bandName
і ми можемо з'єднати ці два разом за допомогою підпиту
select
venueName
from (
select
P.venueName, COUNT(distinct B.bandCountry) as VenueBandCountryCount
from PLAYS P
inner join BAND B on B.bandName = P.bandName
) X
where X.VenueBandCountryCount = @BandCountryCount
Тепер це не найкрасивіший можливий запит (GROUP BY і HAVING можна вважати більш «елегантним» рішенням, ніж тимчасові змінні та підзапит), але це досить очевидно, за чим ми підемо, тому ми залишимо це на користь ОП .
Метою ОП було навчитися перемикати мислення з імперативного на декларативне. З цією метою подивіться, що робило описане імперативне рішення:
для кожного місцяНазвіть назву для всіх груп країн і для кожної групи країн отримайте список гуртів, що виходять з нього. Якщо жоден з них не грає в venueName, перейдіть до наступного ім'яName. В іншому випадку, в кінці діапазону ітерація країн додає venueName до набору хороших місць знамення
Які визначальні критерії у вищезазначеному? Я думаю це:
... Якщо жоден з них [набір гуртів з певної країни] не грає на місці проведення імені ...
Це критерії дискваліфікації . Імперативний процес думки починається з повного відра і викидає речі, що не відповідають критеріям. Ми фільтруємо дані.
Це добре для простих речей, але це допомагає мислити з точки зору побудови потрібного набору результатів; які відповідні кваліфікаційні критерії дозволяють замість цього заповнити відро?
- дискваліфікатор: якщо немає групи з групиCountry, яка грає в місці, місце проведення дискваліфікується
- (частковий) класифікатор: якщо принаймні одна група з bandCountry грає на місці, то місце може бути нормальним; продовжуйте перевіряти решту груп країн
- (повний) класифікатор: якщо принаймні один гурт з кожного гуртуCountry грає на місці, то місце проведення кваліфікації
Кінцевий класифікатор можна спростити за допомогою підрахунків: bandCountry "задоволений", якщо принаймні одна група звідти грає на місці; кількість "задоволених" країн гурту для місця проведення має бути рівним кількості країн групи для проведення місця проведення кваліфікації.
Тепер ми можемо міркувати між відносинами за допомогою навігації:
- Почніть з відношення VENUE [нам це не потрібно для відповіді, але це концептуальна відправна точка для реляційної навігації]
- приєднайтесь до PLAYS на venueName
- приєднайтесь до BAND на bandName, щоб отримати bandCountry
- нас не хвилює назва гурту; виберіть лише місце імені та назву смуги
- нас не хвилює зайві групи країн; усуньте дублікати за допомогою DISTRICT або GROUP BY
- нас хвилює лише кількість чітких країн, а не назви
- ми хочемо лише місць, де кількість чітких країн групи збігається з загальною кількістю bandCountries
що призводить назад до рішення вище (або його розумного факсимільного опису)
ПІДСУМОК
- теорія множин
- реляційні навігаційні шляхи
- включно проти ексклюзивних критеріїв (від кваліфікації до дискваліфікації)