Dúvida com SQL
bom dia a todos
seguinte: preciso de ajuda pra montar uma consulta SQL com as seguintes condições
tenho uma tabela de filiais com a seguinte estrutura:
[b:04da4a6fdc]fil_nome[/b:04da4a6fdc] | [b:04da4a6fdc]fil_cidade[/b:04da4a6fdc]
empresa a | cidade a
empresa a | cidade b
empresa b | cidade a
empresa b | cidade b
empresa c | cidade b
empresa d | cidade a
empresa d | cidade c
preciso listar as empresas que tenham filiais em todas as cidades de uma empresa.
ex: se eu passar a empresa a como parâmetro, ele tem que retornar empresa a e empresa b, pq a b tem filiais em todas as cidades onde tem a empresa a (cidade a e cidade b).
se passar a c, ele tem que retornar empresa a, empresa b e empresa c, pq todas elas tem filiais na cidade b.
consegui fazer listar todas as filiais de uma cidade (fácil), mas quando é pra listar TODAS não consigo.
uso delphi 7, com PostgreSQL e conexão ADO.
grato.
seguinte: preciso de ajuda pra montar uma consulta SQL com as seguintes condições
tenho uma tabela de filiais com a seguinte estrutura:
[b:04da4a6fdc]fil_nome[/b:04da4a6fdc] | [b:04da4a6fdc]fil_cidade[/b:04da4a6fdc]
empresa a | cidade a
empresa a | cidade b
empresa b | cidade a
empresa b | cidade b
empresa c | cidade b
empresa d | cidade a
empresa d | cidade c
preciso listar as empresas que tenham filiais em todas as cidades de uma empresa.
ex: se eu passar a empresa a como parâmetro, ele tem que retornar empresa a e empresa b, pq a b tem filiais em todas as cidades onde tem a empresa a (cidade a e cidade b).
se passar a c, ele tem que retornar empresa a, empresa b e empresa c, pq todas elas tem filiais na cidade b.
consegui fazer listar todas as filiais de uma cidade (fácil), mas quando é pra listar TODAS não consigo.
uso delphi 7, com PostgreSQL e conexão ADO.
grato.
Alanporto
Curtidas 0
Respostas
Afarias
06/10/2009
Humm.. de cara só consigo pensar no SQL abaixo:
select a.fil_nome from tabela a
where exists (select 1 from tabela
where fil_cidade=a.fil_cidade and fil_nome=:p_nome)
group by a.fil_nome
having count(*)>=(select count(*) from tabela
where a.fil_nome=:p_nome);
Bom, isso para FB... eu não conheço PostgreSQL bem... mas dai vc tira... Por exemplo, se o PostgreSQL não suportar EXISTS vc pode converter para IN:
select a.fil_nome from tabela a
where a.fil_cidade IN (select fil_cidade from tabela
where fil_nome=:p_nome)
group by a.fil_nome
having count(*)>=(select count(*) from tabela
where a.fil_nome=:p_nome);
T+
select a.fil_nome from tabela a
where exists (select 1 from tabela
where fil_cidade=a.fil_cidade and fil_nome=:p_nome)
group by a.fil_nome
having count(*)>=(select count(*) from tabela
where a.fil_nome=:p_nome);
Bom, isso para FB... eu não conheço PostgreSQL bem... mas dai vc tira... Por exemplo, se o PostgreSQL não suportar EXISTS vc pode converter para IN:
select a.fil_nome from tabela a
where a.fil_cidade IN (select fil_cidade from tabela
where fil_nome=:p_nome)
group by a.fil_nome
having count(*)>=(select count(*) from tabela
where a.fil_nome=:p_nome);
T+
GOSTEI 0
Alanporto
06/10/2009
suporta sim.
vou testar e depois retorno se funcionou.
valeu afarias.
vou testar e depois retorno se funcionou.
valeu afarias.
GOSTEI 0
Adilsond
06/10/2009
SELECT DISTINCT B.FIL_NOME,B.FIL_CIDADE FROM FILIAIS A, FILIAIS B WHERE A.FIL_NOME = :EMPRESA AND B.FIL_CIDADE = A.FIL_CIDADE
GOSTEI 0
Alanporto
06/10/2009
a resposta do AdilsonD é semelhante o que eu já tinha feito, e a do afarias retornou uma filial que só tinha em uma das cidades.
lembrando: precisa ser exclusivamente em todas as cidades onde há filiais da empresa.
vo tentando aqui com base na consulta do afarias, qualquer resultado retorno.
grato.
lembrando: precisa ser exclusivamente em todas as cidades onde há filiais da empresa.
vo tentando aqui com base na consulta do afarias, qualquer resultado retorno.
grato.
GOSTEI 0
Adilsond
06/10/2009
Faça o seguinte exemplo:
depois
Se o código passado por mim anteriormente não funcionou é porque seus dados não devem possuir uma relação. Verifique os resultados executando separadamente as consultas acima.
SELECT A.FIL_NOME,A.FIL_CIDADE FROM FILIAIS A WHERE A.FIL_NOME = ´empresa a´
depois
SELECT B.FIL_NOME,B.FIL_CIDADE FROM FILIAIS B WHERE B.FIL_CIDADE = ´cidade a´
Se o código passado por mim anteriormente não funcionou é porque seus dados não devem possuir uma relação. Verifique os resultados executando separadamente as consultas acima.
GOSTEI 0
Emerson Nascimento
06/10/2009
não testei, mas...
select *
from filiais a
left join filiais b on b.fil_cidade = a.fil_cidade
where a.fil_nome = ´empresa a´
ou
select *
from filiais a
where a.fil_nome = ´empresa a´
union all
select *
from filiais b
where b.fil_cidade in
(select c.fil_cidade
from filiais c
where c.fil_nome = ´empresa a´)
select *
from filiais a
left join filiais b on b.fil_cidade = a.fil_cidade
where a.fil_nome = ´empresa a´
ou
select *
from filiais a
where a.fil_nome = ´empresa a´
union all
select *
from filiais b
where b.fil_cidade in
(select c.fil_cidade
from filiais c
where c.fil_nome = ´empresa a´)
GOSTEI 0
Alanporto
06/10/2009
valeu, emerson, mas não funcionou (acho que eu não expliquei muito bem também...), AdilsonD, sei que os dados estão meio confusos (não faria a estrutura dessa forma, mas fazer o que?), mas a tabela é aquilo que passei no primeiro post.
tentar explicar direito: o retorno deve ser as empresas que tem filiais em todas as cidades onde também tem filiais da empresa passada. Se fosse uma cidade só era fácil:
mas se eu usar um subselect pra trazer as cidades e usar IN (fil_cidade IN <subselect>), ele considera qualquer filial que exista em qualquer cidade.
a saída desejada é essa, para o parâmetro:
Empresa a: a,b (ambas tem nas cidades a e b)
Empresa b: a,b (ambas tem nas cidades a e b)
Empresa c: a,b,c (todas elas tem filiais na cidade b)
Empresa d: nulo (ninguém mais tem empresas na cidade a e c)
espero ter explicado direito, valeu pela ajuda!!
ps: tentei usar in all, except e intersect, mas não consegui (mas talvez seja por aí)
tentar explicar direito: o retorno deve ser as empresas que tem filiais em todas as cidades onde também tem filiais da empresa passada. Se fosse uma cidade só era fácil:
select fil_nome from filiais where fil_cidade = ´cidade a´
mas se eu usar um subselect pra trazer as cidades e usar IN (fil_cidade IN <subselect>), ele considera qualquer filial que exista em qualquer cidade.
a saída desejada é essa, para o parâmetro:
Empresa a: a,b (ambas tem nas cidades a e b)
Empresa b: a,b (ambas tem nas cidades a e b)
Empresa c: a,b,c (todas elas tem filiais na cidade b)
Empresa d: nulo (ninguém mais tem empresas na cidade a e c)
espero ter explicado direito, valeu pela ajuda!!
ps: tentei usar in all, except e intersect, mas não consegui (mas talvez seja por aí)
GOSTEI 0
Afarias
06/10/2009
|a do afarias retornou uma filial que só tinha em uma das cidades.
Interessante, testando com os dados q vc passou isso não acontece comigo usando FB.
T+
Interessante, testando com os dados q vc passou isso não acontece comigo usando FB.
T+
GOSTEI 0
Alanporto
06/10/2009
mas seu retorno bateu com o q eu expliquei agora? pq tentei no FB tbm (na verdade prefiro FB) e não deu certo também (acho que tô meio zicado...)
GOSTEI 0
Afarias
06/10/2009
sim, o retorno bateu perfeitamente com seu exemplo
GOSTEI 0
Afarias
06/10/2009
talvez seja a questão do parâmetro. note q o mesmo valor (parâmetro) é declarado 2 vezes (em 2 locais) na consulta.
T+
T+
GOSTEI 0
Emerson Nascimento
06/10/2009
ah... agora entendi... você quer retornar as empresas que estejam exatamante nas mesmas cidades (em todas elas).
tente assim:
tente assim:
select b.fil_nome from filiais b where b.fil_cidade in ( select a.fil_cidade from filiais a where a.fil_nome=´empresa a´ ) group by b.fil_nome having count(*) = (select count(*) from filiais a where a.fil_nome=´empresa a´)
GOSTEI 0
Alanporto
06/10/2009
emerson, ainda não deu... caiu no mesmo caso da do afarias, se eu passo a empresa a ele retorna a,b,d.
afarias, valeu por responder, mas eu troquei o parâmetro por ´empresa a´ e ainda retornou a empresa d.
afarias, valeu por responder, mas eu troquei o parâmetro por ´empresa a´ e ainda retornou a empresa d.
GOSTEI 0
Afarias
06/10/2009
Opa Alan,
não estava compreendendo como pode dar certo para mim e não dar certo para vc e ai vi no código q postei tem um pequeno erro de sintaxe que faz o resultado aparecer errado.
O código correto q eu estava testando (e dá certo) É:
select a.fil_nome from tabela a
where exists (select 1 from tabela
where fil_cidade=a.fil_cidade and fil_nome=:p_nome)
group by a.fil_nome
having count(*)>=(select count(*) from tabela
where [b:1aa394a114]fil_nome[/b:1aa394a114]=:p_nome);
NOTE a correção na última linha (em negrito) ... eu tinha postado a.fil_nome quando o correto é apenas fil_nome pois o campo deve ser do sub-select e não da consulta principal
=)
Era só isso, desculpe.
T+
não estava compreendendo como pode dar certo para mim e não dar certo para vc e ai vi no código q postei tem um pequeno erro de sintaxe que faz o resultado aparecer errado.
O código correto q eu estava testando (e dá certo) É:
select a.fil_nome from tabela a
where exists (select 1 from tabela
where fil_cidade=a.fil_cidade and fil_nome=:p_nome)
group by a.fil_nome
having count(*)>=(select count(*) from tabela
where [b:1aa394a114]fil_nome[/b:1aa394a114]=:p_nome);
NOTE a correção na última linha (em negrito) ... eu tinha postado a.fil_nome quando o correto é apenas fil_nome pois o campo deve ser do sub-select e não da consulta principal
=)
Era só isso, desculpe.
T+
GOSTEI 0
Alanporto
06/10/2009
que nada! valeu por ajudar, agora funcionou. valeu à todos!!
GOSTEI 0