pense em termos de conjuntos, não em iteradores; as instruções sql definem as propriedades do conjunto de saída desejado (também conhecido como tabela / relação)
Todos os locais de eventosNomes que, para cada bandaPaís, há uma banda daquele país que toca no local com esse nome
o resultado disso (se eu entendi suas intenções corretamente!) seria o conjunto de locais que possuem pelo menos uma banda que toca nesse local. A iteração sobre bandCountry é desnecessária, pois a relação PLAYS já possui as informações que você procura, basta eliminar as duplicatas
então no SQL isso seria:
select
distinct venueName
from PLAYS
EDIT: ok, então o conjunto real desejado é um pouco mais complicado. A pergunta que está sendo feita ao banco de dados é: quais locais hospedaram bandas de todos os países?
Assim, definimos os critérios de associação para um elemento do conjunto desejado como a meta e, em seguida, trabalhamos para trás para preencher o conjunto. Um local é um membro do conjunto de saída se tiver uma linha do PLAYS para pelo menos uma banda de cada país. Como obtemos essa informação?
Uma maneira é contar os países distintos para cada local e compará-lo com a contagem de todos os países. Mas não temos uma relação com PAÍS. Se pensarmos no modelo dado por um momento, veremos que o conjunto de todos os países não é o critério certo; é o conjunto de todos os países que têm pelo menos uma banda. Portanto, não precisamos de uma tabela de países (embora, para um modelo normalizado, devêssemos ter uma), e não nos importamos com o país do local, podemos apenas contar os países que têm bandas, por exemplo (no MS-SQL )
declare @BandCountryCount int
select
@BandCountryCount = COUNT(distinct bandCountry)
from BAND
Podemos contar os países da banda para cada local
select
P.venueName, COUNT(distinct B.bandCountry) as VenueBandCountryCount
from PLAYS P
inner join BAND B on B.bandName = P.bandName
e podemos juntar os dois usando uma subconsulta
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
Agora, essa não é a consulta mais bonita possível (GROUP BY e HAVING pode ser considerado uma solução mais 'elegante' do que variáveis temporárias e uma subconsulta), mas é bastante óbvio o que buscamos, portanto, deixamos isso para o objetivo do OP .
O objetivo do OP era aprender a mudar a mentalidade de imperativo para declarativo. Para esse fim, observe o que a solução imperativa descrita estava fazendo:
para cada local de nome, repita todos os países da banda e, para cada país da banda, obtenha a lista de bandas que vêm dele. Se nenhum deles jogar no venueName, vá para o próximo venueName. Caso contrário, no final da banda, a iteração dos países adiciona venueName ao conjunto de boas instalaçõesNames
Quais são os critérios determinantes acima? Eu acho que é:
... Se nenhum deles [o conjunto de bandas de um país em particular] tocar no localNome ...
Este é um critério desqualificante . O processo de pensamento imperativo está começando com um balde cheio e jogando fora coisas que não se encaixam nos critérios. Estamos filtrando os dados.
Isso é bom para coisas simples, mas ajuda a pensar em termos de construção do conjunto de resultados desejado; quais são os critérios de qualificação correspondentes que permitiriam preencher o balde?
- desqualificador: se não houver banda de um país da banda que toca em um local, o local é desqualificado
- qualificador (parcial): se pelo menos uma banda de um país da banda tocar em um local, o local poderá estar ok; continue verificando o resto da banda
- qualificador (completo): se pelo menos uma banda de cada país tocar em um local, o local será qualificado
O qualificador final pode ser simplificado usando contagens: um país da banda fica 'satisfeito' se pelo menos uma banda dali tocar em um local; o número de países da banda 'satisfeitos' para um local de reunião deve ser igual ao número de países da banda para que o local seja qualificado.
Agora podemos raciocinar através das relações pela navegação:
- comece com a relação VENUE [não precisamos dela para a resposta, mas é o ponto de partida conceitual para a navegação relacional]
- junte-se ao PLAYS no local
- junte-se ao BAND no nome da banda para obter a banda
- nós não nos importamos com o nome da banda; selecione apenas o localNome e bandaPaís
- nós não nos importamos com os países de banda redundantes; eliminar duplicatas usando DISTRICT ou GROUP BY
- nos preocupamos apenas com a contagem de países de banda distintos, não com os nomes
- queremos apenas locais onde a contagem de bandCountries distintos seja igual ao número total de bandCountries
que leva de volta à solução acima (ou a um fax razoável)
RESUMO
- teoria de conjuntos
- caminhos de navegação relacional
- critérios inclusivos x exclusivos (qualificação x desqualificação)