myśl w kategoriach zbiorów, a nie iteratorów; instrukcje sql definiują właściwości pożądanego zestawu danych wyjściowych (inaczej tabela / relacja)
all venue Nazwy takie, że dla każdego zespołu Country istnieje zespół z tego kraju, który gra w miejscu o tej nazwie
wynikiem tego (jeśli dobrze zrozumiałem twoje intencje!) byłby zestaw miejsc, w których przynajmniej jeden zespół gra w tym miejscu. Iteracja nad bandCountry nie jest konieczna, ponieważ relacja PLAYS już zawiera informacje, których szukasz, po prostu musisz wyeliminować duplikaty
więc w SQL byłoby to:
select
distinct venueName
from PLAYS
EDYCJA: ok, więc faktyczny pożądany zestaw jest nieco bardziej skomplikowany. Baza danych zadaje pytanie: jakie miejsca gościły zespoły ze wszystkich krajów?
Tak więc definiujemy kryteria członkostwa dla elementu pożądanego zestawu jako cel, a następnie pracujemy wstecz, aby wypełnić zestaw. Miejsce jest członkiem zestawu wyników, jeśli ma wiersz PLAYS dla co najmniej jednego zespołu z każdego kraju. Jak uzyskać te informacje?
Jednym ze sposobów jest policzenie różnych krajów dla każdego miejsca i porównanie ich z liczbą wszystkich krajów. Ale nie mamy relacji KRAJ. Jeśli zastanowimy się przez chwilę nad modelem, zobaczymy, że zbiór wszystkich krajów nie jest właściwym kryterium; to zbiór wszystkich krajów, które mają co najmniej jeden zespół. Nie potrzebujemy więc tabeli kraju (chociaż w przypadku znormalizowanego modelu powinniśmy ją mieć) i nie dbamy o kraj miejsca, możemy po prostu policzyć kraje, które mają pasma, np. (W MS-SQL )
declare @BandCountryCount int
select
@BandCountryCount = COUNT(distinct bandCountry)
from BAND
Możemy policzyć kraje zespołu dla każdego miejsca
select
P.venueName, COUNT(distinct B.bandCountry) as VenueBandCountryCount
from PLAYS P
inner join BAND B on B.bandName = P.bandName
i możemy poskładać je razem za pomocą podzapytania
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
To nie jest najładniejsze możliwe zapytanie (GROUP BY i HAVING można uznać za bardziej „eleganckie” rozwiązanie niż zmienne tymczasowe i podzapytanie), ale to dość oczywiste, o co nam chodzi, więc zostawimy to na cel PO .
Celem PO było nauczenie się, jak zmienić sposób myślenia z imperatywnego na deklaratywny. W tym celu spójrz na to, co robiło opisane imperatywne rozwiązanie:
dla każdego miejsca Nazwa powtarza się po wszystkich bandCountries i dla każdego bandCountry pobierz listę zespołów, które z niego pochodzą. Jeśli żadne z nich nie gra w venueName, przejdź do następnego venueName. W przeciwnym razie na końcu pasma iteracji Krajów dodaj venueName do zestawu dobrych venueNames
Jakie są powyższe kryteria? Myślę, że to jest:
... Jeśli żaden z nich [zestaw zespołów z określonego kraju] nie gra w VenueName ...
To są kryteria dyskwalifikujące . Konieczny proces myślenia rozpoczyna się od pełnego wiadra i wyrzucania rzeczy, które nie spełniają kryteriów. Jesteśmy filtrowanie danych.
To proste w przypadku prostych rzeczy, ale pomaga myśleć w kategoriach konstruowania pożądanego zestawu wyników; jakie są odpowiednie kryteria kwalifikacyjne , które pozwoliłyby zamiast tego wypełnić wiadro?
- dyskwalifikator: jeśli nie ma zespołu z kraju, który gra w danym miejscu, miejsce jest zdyskwalifikowane
- (częściowy) kwalifikator: jeśli co najmniej jeden zespół z bandCountry gra w danym miejscu, to miejsce może być w porządku; sprawdzaj resztę bandCountries
- (pełny) kwalifikator: jeśli co najmniej jeden zespół z każdego zespołu Kraj gra w miejscu, to miejsce jest kwalifikowane
Ostateczny kwalifikator można uprościć za pomocą liczników: bandCountry jest „zadowolony”, jeśli przynajmniej jeden zespół stamtąd gra w danym miejscu; liczba „zadowolonych” krajów zespołu dla danego miejsca musi być równa liczbie krajów zespołu dla danego miejsca, które ma zostać zakwalifikowane.
Teraz możemy uzasadnić relacje między nawigacjami:
- zacznij od relacji MIEJSCE [nie potrzebujemy jej do odpowiedzi, ale jest to koncepcyjny punkt wyjścia do nawigacji relacyjnej]
- dołącz do PLAYS na venueName
- dołącz do BAND na bandName, aby uzyskać bandCountry
- nie obchodzi nas nazwa zespołu; wybierz tylko nazwę miejsca i bandCountry
- nie dbamy o redundantne bandCountries; eliminuj duplikaty za pomocą DISTRICT lub GROUP BY
- zależy nam tylko na liczbie odrębnych krajów band, a nie na nazwach
- chcemy tylko miejsc, w których liczba odrębnych bandCountries jest taka sama jak całkowita liczba bandCountries
co prowadzi do powyższego rozwiązania (lub jego uzasadnionego faksu)
PODSUMOWANIE
- teoria mnogości
- relacyjne ścieżki nawigacji
- kryteria włączające vs wyłączne (kwalifikacje vs dyskwalifikacja)