none
Dúvida sub consulta RRS feed

  • Pergunta

  • Olá pessoALL,

    Que operador SQL utilizo para verificar quais registros da tabela A se relacionam com todos os registros da tabela B. Operação semelhante à divisão da algebra relacional.


    Segue exemplo:
    Quero todos cddepto que possuam homens e mulheres trabalhando.
    O resultado deve ser cddepto 1 pois cddepto 2 só tem homens trabalhando.

    tabela funcionario
    nm_func, cddepto, sexo
    A 1 M
    B 1 F
    C 2 M

    o resultado

    cddepto
    1

    O :
    select cddepto from funcionario where sexo = all(select distinct sexo from funcionario )

    não funcionou, trouxe zero registros.

    Obrigado.

    terça-feira, 10 de junho de 2008 13:29

Todas as Respostas

  • Diogo,

     

    Se você deseja utilizar um operador poderia ser o IN, Exists!!!

     

    Agora outra possibilidade seria utilizar um Join.

    terça-feira, 10 de junho de 2008 14:35
  • Bom Dia,

     

    A álgebra relacional tem os fundamentos para os bancos de dados relacionais, mas nem sempre as implementações são mapeadas de forma tão direta. Receio que não haja implementação ANSI para esse tipo de operação na álgebra relacional. Podemos usar uma construção alternativa. Ex:

     

    Code Snippet

    SELECT cddepto FROM Funcionario AS Func

    GROUP BY cddepto

    HAVING COUNT(DISTINCT Sexo) = (SELECT COUNT(DISTINCT Sexo) FROM Funcionario)

     

    [ ]s,

     

    Gustavo

    terça-feira, 10 de junho de 2008 14:37
  • Eu pensei em algo parecido com o Gustavo,

    Code Snippet

     

    create table #funcionario (nm_func Char(1), cdDepto tinyInt, Sexo Char(1))

    insert into #funcionario(nm_func, cdDepto, Sexo) values('A', 1, 'M')

    insert into #funcionario(nm_func, cdDepto, Sexo) values('B', 1, 'F')

    insert into #funcionario(nm_func, cdDepto, Sexo) values('C', 2, 'M')

     

    SELECT DISTINCT cddepto

    FROM #funcionario AS a

    WHERE (SELECT COUNT(DISTINCT Sexo)

    FROM #funcionario

    WHERE #funcionario.cdDepto = a.cdDepto) = 2

     

     

     

    terça-feira, 10 de junho de 2008 14:49
  • Funcionou da seguinte forma:

     

    SELECT D.CDDEPTO

    FROM DEPARTAMENTOS AS D

    WHERE

    (EXISTS (SELECT F.CDDEPTO FROM FUNCIONARIOS AS F WHERE F.CDDEPTO = D.CDDEPTO AND SEXO = 'M'))

    AND

    (EXISTS (SELECT F.CDDEPTO FROM FUNCIONARIOS AS F WHERE F.CDDEPTO = D.CDDEPTO AND SEXO = 'F'))

     

     

    Muito obrigado!

    terça-feira, 10 de junho de 2008 14:50
  • Olá Diogo,

     

    Diversos operadores da álgebra relacional como seleção, projeção, junção, semijunção, antijunção, etc são diretamente mapeáveis para instruções SQL implementadas (ANSI Compliance). O problema é que álgebra relacional representa a teoria dos conjuntos e nem todas as operações são diretamente mapeáveis.

     

    A sua solução certamente funciona, mas ela possui uma forte limitação. Você teve de conhecer previamente a relação de sexos possíveis (no caso M e F). Embora alguns lugares como o ministério da saúde considere 9 valores possíveis para sexo, é bem provável que você considere apenas esses valores sempre e que isso nunca vá mudar. No entanto, se você for aplicar o mesmo raciocínio para outras situações esse tipo de construção é muito limitado.

     

    Suponha por exemplo que ao invés de sexo, você quisesse tratar tipos de profissionais (engenheiro, gerente, estagiário, etc) e quisesse saber que departamento tem todos os tipos de profissionais. Bastaria a entrada de um novo tipo de profissional que sua consulta deixaria de funcionar.

     

    Por isso recomendo utilizar construções que não sejam tão vulneráveis. Afinal se for necessário um conhecimento prévio sobre os dados sua consulta está mais acoplada do que o necessário. No SQL Server 2005 é possível fazer outras se você utilizar operadores como INTERSECT e EXCEPT, mas creio que as soluções apresentadas já são suficientes.

     

    [ ]s,

     

    Gustavo

     

    terça-feira, 10 de junho de 2008 15:04