Select com dupla condição para o mesmo campo

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
roseane
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Qua, 27 Jan 2010 4:13 pm
Localização: Volta Redonda - RJ

Boa tarde,
Estou criando uma consulta tipo filtro de pessoas cadastradas, em php e preciso gerar um sql a partir das escolhas do usuário no filtro. Dentre as opções, uma pessoa pode participar de vários projetos sociais. Eu preciso selecionar exatamente uma pessoa que participe de um ou mais projetos específicos, em uma tabela de relacionamento, por exemplo:

Selecionar tudo

select count(*) from pessoa_projetos where projeto_id = 1 and projeto_id = 5
No exemplo, eu preciso selecionar o numero de pessoas que participam do projeto 1 e 5. Eu sei que a condição em negrito é inválida, eu só coloquei para explicar o que eu preciso. Não consegui montar um sql que atenda a essa condição, você pode me ajudar?

Desde já agradeço,
Roseane.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Você precisa consultar a tabela duas vezes, senão sua condição nunca será verdadeira, pois o campo projeto_id só pode ter um valor por linha.

Selecionar tudo

select *
  from pessoa_projetos p1
  join pessoa_projetos p2 on p1.id_pessoa = p2.id_pessoa
 where p1.projeto_id = 1 and p2.projeto_id = 5
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Selecionar tudo

select count(*) from pessoa_projetos
 where projeto_id in (1,5) 

?
roseane
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Qua, 27 Jan 2010 4:13 pm
Localização: Volta Redonda - RJ

Bom dia a todos
diegolenhardt, eu não posso usar o in porque ele traria por exemplo, todas as pessoas que participam do projeto 1 ou 5, eu preciso trazer pessoas que participam dos projetos 1 e 5. Vou testar a sugestão do fsitja e já posto aqui o resultado.

Obrigada!
Roseane
roseane
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Qua, 27 Jan 2010 4:13 pm
Localização: Volta Redonda - RJ

Eu testei a sugestao do fsitja e funcionou :D Mas como a possibilidade de escolha é de até 5 projetos, e isso pode se expandir, então no caso da consulta da participação de pessoas em 5 projetos, teria que fazer 5 consultas na tabela. Não teria como trazer o resultado usando uma consulta só e cada resultado numa linha?

Roseane
eduardobogoni
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 1
Registrado em: Qui, 28 Jan 2010 8:00 am
Localização: Volta Redonda - RJ

Poste o esquema das tabelas que está sendo utilizado e os dados dessas mesmas tabelas para que possamos compreender melhor o problema.
roseane
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Qua, 27 Jan 2010 4:13 pm
Localização: Volta Redonda - RJ

Um exemplo de dados da tabela:

Selecionar tudo

PESSOA_ID | PROJETO_ID
roseane
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Qua, 27 Jan 2010 4:13 pm
Localização: Volta Redonda - RJ

Um exemplo dos dados:

Selecionar tudo

PESSOA_ID | PROJETO_ID
     82   |        1
     82   |        5
     90   |        5
     94   |        2
     102  |        1
     102  |        4

Eu queria montar um sql que me trouxesse um resultado do tipo:

Selecionar tudo

PESSOA_ID | PROJETO_ID
     82   |        1
     82   |        5
ao selecionar as pessoas que trabalham no projeto 1 e 5 em apenas uma consulta, se for possível
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Montei um SQL que agrega num string os projetos de uma pessoa e depois usando expressão regular extrai os projetos dos quais ela participou.

Você precisa ter Oracle versão 10g para funcionar esse SQL.

No exemplo abaixo no WHERE coloquei 3 REGEXP_LIKE, um para cada projeto que quero que a pessoa tenha participado (projetos 2, 3 e 4).
É só modificar ali dentro e colocar os números que você quiser. Se quiser que a pessoa tenha participado em 10 projetos, vai ter que adicionar 10 linhas no WHERE com 10 vezes copiado o REGEXP_LIKE mudando só o código do projeto.

Selecionar tudo

WITH pessoa_projetos AS
 (SELECT 82 pessoa_id, 1 projeto_id FROM dual UNION ALL
  SELECT 82, 5 FROM dual UNION ALL
  SELECT 90, 5 FROM dual UNION ALL
  SELECT 94, 2 FROM dual UNION ALL
  SELECT 102, 1 FROM dual UNION ALL
  SELECT 102, 2 FROM dual UNION ALL
  SELECT 102, 3 FROM dual UNION ALL  
  SELECT 102, 4 FROM dual)
-- fim dos dados de exemplo
SELECT pessoa_id, lista_proj_pess, qtd_proj_pess
  FROM (SELECT pessoa_id,
               sys_connect_by_path(projeto_id, '\') lista_proj_pess,
               LEVEL qtd_proj_pess
          FROM (SELECT pp.*,
                       row_number() over(PARTITION BY pessoa_id ORDER BY projeto_id) num_proj_pess
                  FROM pessoa_projetos pp)
         WHERE connect_by_isleaf = 1
         START WITH num_proj_pess = 1
        CONNECT BY PRIOR (pessoa_id) = pessoa_id
                   AND PRIOR (num_proj_pess) + 1 = num_proj_pess)
 WHERE regexp_like(lista_proj_pess, '\\2\\*') -- coloque o código do projeto
       AND regexp_like(lista_proj_pess, '\\3\\*') -- um código para cada linha
       AND regexp_like(lista_proj_pess, '\\4\\*')
Segue abaixo exemplo da execução:

Selecionar tudo

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 
Connected as fsitja
 
SQL> 
SQL> WITH pessoa_projetos AS
  2   (SELECT 82 pessoa_id, 1 projeto_id FROM dual UNION ALL
  3    SELECT 82, 5 FROM dual UNION ALL
  4    SELECT 90, 5 FROM dual UNION ALL
  5    SELECT 94, 2 FROM dual UNION ALL
  6    SELECT 102, 1 FROM dual UNION ALL
  7    SELECT 102, 2 FROM dual UNION ALL
  8    SELECT 102, 3 FROM dual UNION ALL
  9    SELECT 102, 4 FROM dual)
 10  -- fim dos dados de exemplo
 11  SELECT pessoa_id, lista_proj_pess, qtd_proj_pess
 12    FROM (SELECT pessoa_id,
 13                 sys_connect_by_path(projeto_id, '\') lista_proj_pess,
 14                 LEVEL qtd_proj_pess
 15            FROM (SELECT pp.*,
 16                         row_number() over(PARTITION BY pessoa_id ORDER BY projeto_id) num_proj_pess
 17                    FROM pessoa_projetos pp)
 18           WHERE connect_by_isleaf = 1
 19           START WITH num_proj_pess = 1
 20          CONNECT BY PRIOR (pessoa_id) = pessoa_id
 21                     AND PRIOR (num_proj_pess) + 1 = num_proj_pess)
 22   WHERE regexp_like(lista_proj_pess, '\\2\\*')
 23         AND regexp_like(lista_proj_pess, '\\3\\*')
 24         AND regexp_like(lista_proj_pess, '\\4\\*')
 25  /
 
 PESSOA_ID LISTA_PROJ_PESS        QTD_PROJ_PESS
---------- ---------------------- -------------
       102 \1\2\3\4                           4
 
SQL> 
Abraços,
Francisco.
burga
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Qui, 26 Nov 2009 1:05 pm
Localização: SP

Você pode fazer assim:

Selecionar tudo

select id_pessoa from (
  select * 
  from pessoa_projetos p1
  where p1.projeto_id = 1 or p1.projeto_id = 5 ) t1
group by t1.id_pessoa having count(*) > 1;
adicionando somente os projetos na clausula where da subquery e alterando o numero da expressão having count(*) >1
roseane
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Qua, 27 Jan 2010 4:13 pm
Localização: Volta Redonda - RJ

Obrigada pela ajuda pessoal. Vou adaptar as sugestões no código do sistema.

Abraços,
Roseane
SergioLBJr
Rank: Oracle Guru
Rank: Oracle Guru
Mensagens: 448
Registrado em: Ter, 16 Jun 2009 3:07 pm
Localização: Parobé - RS
Sérgio Luiz Bonemberger Junior
Programador Junior
Parobé RS

[]s

se tu conseguir pode fazer a tua clausula where dinâmica.

Tipo , cria uma variavel que recebe todo o where que tu quer e adiciona ela na query com um &variavel.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 19 visitantes