berpikir dalam hal set, bukan iterator; pernyataan sql mendefinisikan properti set output yang diinginkan (alias tabel / relasi)
semua venueNames sedemikian rupa sehingga untuk setiap bandCountry ada band dari negara itu yang bermain di venue nama itu
hasil dari ini (jika saya memahami maksud Anda dengan benar!) akan menjadi himpunan tempat yang memiliki setidaknya satu band yang bermain di tempat itu. Iterasi atas bandCountry tidak perlu, karena relasi PLAYS sudah memiliki informasi yang Anda cari, Anda hanya perlu menghilangkan duplikat
jadi dalam SQL ini akan menjadi:
select
distinct venueName
from PLAYS
EDIT: ok, jadi set sebenarnya yang diinginkan sedikit lebih rumit. Pertanyaan yang diajukan dari database adalah: venue apa yang telah menjadi tuan rumah band dari semua negara?
Jadi, kami mendefinisikan kriteria keanggotaan untuk elemen set yang diinginkan sebagai tujuan, lalu bekerja mundur untuk mengisi set. Sebuah venue adalah anggota dari set output jika memiliki baris PLAYS untuk setidaknya satu band dari setiap negara. Bagaimana kami mendapatkan informasi ini?
Salah satu caranya adalah dengan menghitung negara yang berbeda untuk setiap tempat dan membandingkannya dengan jumlah semua negara. Tapi kami tidak memiliki hubungan NEGARA. Jika kita memikirkan model yang diberikan untuk sesaat, kita melihat bahwa himpunan semua negara bukanlah kriteria yang tepat; itu adalah himpunan semua negara yang memiliki setidaknya satu band. Jadi kita tidak memerlukan tabel negara (meskipun untuk model yang dinormalisasi kita harus memilikinya), dan kita tidak peduli dengan negara tempat, kita bisa menghitung negara-negara yang memiliki band, misalnya (dalam MS-SQL )
declare @BandCountryCount int
select
@BandCountryCount = COUNT(distinct bandCountry)
from BAND
Kami dapat menghitung negara band untuk setiap venue
select
P.venueName, COUNT(distinct B.bandCountry) as VenueBandCountryCount
from PLAYS P
inner join BAND B on B.bandName = P.bandName
dan kita bisa menyatukan keduanya menggunakan subquery
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
Sekarang, itu bukan permintaan tercantik yang mungkin (GROUP BY dan HAVING mungkin dianggap solusi yang lebih 'elegan' daripada variabel temp dan subquery) tapi cukup jelas apa yang kita cari sehingga kita akan membiarkannya di situ untuk tujuan OP .
Tujuan OP adalah untuk belajar bagaimana mengubah pola pikir dari imperatif ke deklaratif. Untuk itu, lihat apa yang dilakukan oleh solusi imperatif:
untuk setiap venueName, ulangi semua bandCountries dan untuk setiap bandCountry dapatkan daftar band yang berasal darinya. Jika tidak ada yang bermain di venueName, pergi ke venueName berikutnya. Selain itu, pada akhir pengulangan bandCountries, tambahkan venueName ke set venue venue yang baik
Apa kriteria penentu di atas? Aku rasa ini:
... Jika tidak satupun dari mereka [kelompok band dari negara tertentu] bermain di venueName ...
Ini adalah kriteria yang mendiskualifikasi . Proses berpikir imperatif dimulai dengan ember penuh dan membuang hal-hal yang tidak sesuai dengan kriteria. Kami memfilter data.
Itu bagus untuk hal-hal sederhana, tetapi membantu berpikir dalam hal membangun set hasil yang diinginkan; apa kriteria kualifikasi yang sesuai yang akan memungkinkan seseorang untuk mengisi ember sebagai gantinya?
- didiskualifikasi: jika tidak ada band dari bandCountry yang bermain di suatu venue, venue tersebut didiskualifikasi
- kualifikasi (parsial): jika setidaknya satu band dari bandCountry bermain di suatu venue, maka venue tersebut mungkin oke; terus memeriksa sisa bandCountries
- Kualifikasi (penuh): jika setidaknya satu band dari masing-masing bandCountry bermain di suatu venue, maka venue tersebut memenuhi syarat
Kualifikasi akhir dapat disederhanakan menggunakan hitungan: bandCountry 'puas' jika setidaknya satu band dari sana bermain di suatu venue; jumlah negara band 'puas' untuk suatu venue harus sama dengan jumlah negara band untuk tempat yang akan dikualifikasi.
Sekarang kita dapat memberi alasan lintas hubungan dengan navigasi:
- mulai dengan relasi VENUE [kita tidak membutuhkannya untuk jawabannya, tetapi ini adalah titik awal konseptual untuk navigasi relasional]
- bergabunglah dengan PLAYS di venueName
- bergabunglah dengan BAND di bandName untuk mendapatkan bandCountry
- kami tidak peduli dengan nama band; pilih hanya venueName dan bandCountry
- kami tidak peduli tentang band-band yang berlebihan; menghilangkan duplikat menggunakan DISTRICT atau GROUP BY
- kami hanya peduli tentang jumlah band band berbeda, bukan nama
- kami hanya ingin tempat di mana jumlah bandCountries berbeda sama dengan jumlah total bandCountries
yang mengarah kembali ke solusi di atas (atau faksimili yang masuk akal)
RINGKASAN
- teori set
- jalur navigasi relasional
- kriteria inklusif vs eksklusif (kualifikasi vs diskualifikasi)