мыслить в терминах множеств, а не итераторов; 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 можно считать более «элегантным» решением, чем временные переменные и подзапрос), но вполне очевидно, что мы ищем, поэтому мы оставим это для целей OP. ,
Цель ОП заключалась в том, чтобы научиться сдвигать образ мыслей с императивного на декларативный. Для этого посмотрите, что делает описанное императивное решение:
для каждого venueName итерируйте по всем bandCountries и для каждого bandCountry получите список бэндов, которые из него идут. Если никто из них не играет в venueName, перейдите к следующему названию. Иначе, в конце итерации bandCountries добавьте venueName к набору хороших названий.
Что является определяющим критерием в приведенном выше? Я думаю, что это:
... Если ни один из них [набор групп из определенной страны] не играет в venueName ...
Это дисквалифицирующий критерий . Обязательный мыслительный процесс начинается с полного ведра и выбрасывает вещи, которые не соответствуют критериям. Мы фильтруем данные.
Это хорошо для простых вещей, но помогает мыслить с точки зрения построения желаемого набора результатов; каковы соответствующие квалификационные критерии , которые позволили бы вместо этого заполнить ведро?
- дисквалификатор: если нет группы из bandCountry, которая играет на месте, место дисквалифицируется
- (частичный) квалификатор: если хотя бы одна группа из bandCountry играет на месте, то место может быть в порядке; продолжайте проверять остальную часть bandCountries
- (полный) квалификатор: если хотя бы одна группа из каждой группы bandCountry играет в месте проведения, то место проведения квалифицируется
Окончательный классификатор может быть упрощен с помощью счетчиков: bandCountry «удовлетворен», если хотя бы одна группа оттуда играет в месте проведения; количество «удовлетворенных» стран группы для места проведения должно равняться количеству стран группы для места, которое будет квалифицировано.
Теперь мы можем рассуждать через отношения с помощью навигации:
- начнем с отношения VENUE [оно нам не нужно для ответа, но это концептуальная отправная точка для реляционной навигации]
- присоединиться к ИГРОКАМ на venueName
- присоединиться к BAND на bandName, чтобы получить bandCountry
- нас не волнует название группы; выберите только название места и bandCountry
- нас не волнуют избыточные bandCountries; устранить дубликаты с помощью DISTRICT или GROUP BY
- мы заботимся только о количестве отдельных стран, а не об именах
- нам нужны только места, где количество отдельных bandCountries совпадает с общим количеством bandCountries
что приводит к решению выше (или его разумному факсимильному сообщению)
РЕЗЮМЕ
- теория множеств
- реляционные навигационные пути
- включительно против исключительных критериев (квалификация против дисквалификации)