none
Consulta unica e exclusiva RRS feed

  • Pergunta

  • Ola pessoal.

    Tenho uma situação assim:

    Codigo Brinde
    1          a
    1          b
    2          a
    2          c
    3          a
    3          b
    3          c
    4          b
    4          c
    5          a
    5          b
    6          c

    Minha necessidade é conseguir os codigos que tenham (por exemplo) os brindes 'a' e 'b' exclusivamente, que no exemplo seriam o codigo 1 e 5.
    Numa outra consulta somente os codigos que tenham os brindes 'b' e 'c' exclusivamente, que seria o codigo 4.
    E ainda numa outra consulta o codigo que tivesse somente 'c', que seria o 6.

    Agradeço desde já a atenção.

    Abraço.



    sexta-feira, 31 de outubro de 2008 16:19

Respostas

  • Boa Noite HeavyHide,

     

    Seja bem vindo ao fórum de SQL Server no TechNet. Nós participantes do fórum tentaremos lhe ajudar em seus problemas e dúvidas através do conhecimento, experiência e disponibilidade. Se a solução lhe for satisfatório, peço que classifique a resposta marcando-a como respondida.

     

    Esse problema que você está tentando resolver não é tão simples. Não basta apenas colocar um simples IN ou trocar alguns predicados no WHERE. É um problema clássico chamado divisão relacional. Abordei o problema em um Webcast a um tempo atrás e acredito que você vá se interessar. Maiores informações no link abaixo:

     

    Mais dicas e mais truques sobre consultas complexas no SQL Server

    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!190.entry

     

    Para o seu problema específico, desenvolvi uma série de consultas que lhe acredito serem úteis.

     

    Code Snippet

    CREATE TABLE tbl (Codigo INT, Brinde CHAR(1))

     

    INSERT INTO tbl (Codigo, Brinde) VALUES (1,'a')

    INSERT INTO tbl (Codigo, Brinde) VALUES (1,'b')

    INSERT INTO tbl (Codigo, Brinde) VALUES (2,'a')

    INSERT INTO tbl (Codigo, Brinde) VALUES (2,'c')

    INSERT INTO tbl (Codigo, Brinde) VALUES (3,'a')

    INSERT INTO tbl (Codigo, Brinde) VALUES (3,'b')

    INSERT INTO tbl (Codigo, Brinde) VALUES (3,'c')

    INSERT INTO tbl (Codigo, Brinde) VALUES (4,'b')

    INSERT INTO tbl (Codigo, Brinde) VALUES (4,'c')

    INSERT INTO tbl (Codigo, Brinde) VALUES (5,'a')

    INSERT INTO tbl (Codigo, Brinde) VALUES (5,'b')

    INSERT INTO tbl (Codigo, Brinde) VALUES (6,'c')

     

    -- Trazer somente os registros que tenha brindes A e B

    -- Essa consulta está errada, pois, 2 só tem A, 3 tem C e 4 só tem B

    -- Somente 1 e 5 tem somente A e B

    SELECT Codigo, Brinde FROM tbl

    WHERE Brinde IN ('a','b')

     

    -- Agora a consulta só trás quem tem A e B

    -- O NOT EXISTS elimina o 3 que tem A e B mas tem C

    SELECT Codigo

    FROM tbl AS TOut WHERE Brinde IN ('a','b') AND

    NOT EXISTS (

     

    SELECT Codigo FROM tbl AS TInt

    WHERE TOut.Codigo = TInt.Codigo AND TInt.Brinde NOT IN ('A','B'))

     

    GROUP BY Codigo

    HAVING COUNT(DISTINCT Brinde) = 2

     

    -- Consultar os registros que tem somente B e C

    -- Utilizar a mesma solução trocando os valores

    SELECT Codigo

    FROM tbl AS TOut WHERE Brinde IN ('b','c') AND

    NOT EXISTS (

     

    SELECT Codigo FROM tbl AS TInt

    WHERE TOut.Codigo = TInt.Codigo AND TInt.Brinde NOT IN ('b','c'))

     

    GROUP BY Codigo

    HAVING COUNT(DISTINCT Brinde) = 2

     

    -- Consultar os registros que tem somente C

    -- A solução funciona, mas segue uma outra alternativa

    -- O único problema é que é necessário conhecer previamente os brindes

    SELECT Codigo--, [A], [B], [C]

    FROM

    (SELECT Codigo, Brinde FROM tbl) AS TBO

    PIVOT

    (COUNT(Brinde) FOR Brinde IN ([A], [B], [C])) AS TPVT

    WHERE [C] = 1 AND [A] + [B] = 0

     

    [ ]s,

     

    Gustavo

    sexta-feira, 31 de outubro de 2008 22:35

Todas as Respostas

  • Olá Heavyhide use está query

     

    select * from teste where brinde in('a','b')

    sexta-feira, 31 de outubro de 2008 17:41
  • Heavy,

     

    Deixa eu ver se entendi:

     

    - Você deseja fazer um select que traga somente os códigos que possuem os brindes por exemplo 'a' e 'b', outra query que traga 'b' e 'c'.

     

    Mas pode do mesmo código que tem o brinde 'b' ter também o brinde 'c'?

     

    sexta-feira, 31 de outubro de 2008 17:53
    Moderador
  • Será que entendi errado Junior ?

     

    sexta-feira, 31 de outubro de 2008 17:56
  • Boa Noite HeavyHide,

     

    Seja bem vindo ao fórum de SQL Server no TechNet. Nós participantes do fórum tentaremos lhe ajudar em seus problemas e dúvidas através do conhecimento, experiência e disponibilidade. Se a solução lhe for satisfatório, peço que classifique a resposta marcando-a como respondida.

     

    Esse problema que você está tentando resolver não é tão simples. Não basta apenas colocar um simples IN ou trocar alguns predicados no WHERE. É um problema clássico chamado divisão relacional. Abordei o problema em um Webcast a um tempo atrás e acredito que você vá se interessar. Maiores informações no link abaixo:

     

    Mais dicas e mais truques sobre consultas complexas no SQL Server

    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!190.entry

     

    Para o seu problema específico, desenvolvi uma série de consultas que lhe acredito serem úteis.

     

    Code Snippet

    CREATE TABLE tbl (Codigo INT, Brinde CHAR(1))

     

    INSERT INTO tbl (Codigo, Brinde) VALUES (1,'a')

    INSERT INTO tbl (Codigo, Brinde) VALUES (1,'b')

    INSERT INTO tbl (Codigo, Brinde) VALUES (2,'a')

    INSERT INTO tbl (Codigo, Brinde) VALUES (2,'c')

    INSERT INTO tbl (Codigo, Brinde) VALUES (3,'a')

    INSERT INTO tbl (Codigo, Brinde) VALUES (3,'b')

    INSERT INTO tbl (Codigo, Brinde) VALUES (3,'c')

    INSERT INTO tbl (Codigo, Brinde) VALUES (4,'b')

    INSERT INTO tbl (Codigo, Brinde) VALUES (4,'c')

    INSERT INTO tbl (Codigo, Brinde) VALUES (5,'a')

    INSERT INTO tbl (Codigo, Brinde) VALUES (5,'b')

    INSERT INTO tbl (Codigo, Brinde) VALUES (6,'c')

     

    -- Trazer somente os registros que tenha brindes A e B

    -- Essa consulta está errada, pois, 2 só tem A, 3 tem C e 4 só tem B

    -- Somente 1 e 5 tem somente A e B

    SELECT Codigo, Brinde FROM tbl

    WHERE Brinde IN ('a','b')

     

    -- Agora a consulta só trás quem tem A e B

    -- O NOT EXISTS elimina o 3 que tem A e B mas tem C

    SELECT Codigo

    FROM tbl AS TOut WHERE Brinde IN ('a','b') AND

    NOT EXISTS (

     

    SELECT Codigo FROM tbl AS TInt

    WHERE TOut.Codigo = TInt.Codigo AND TInt.Brinde NOT IN ('A','B'))

     

    GROUP BY Codigo

    HAVING COUNT(DISTINCT Brinde) = 2

     

    -- Consultar os registros que tem somente B e C

    -- Utilizar a mesma solução trocando os valores

    SELECT Codigo

    FROM tbl AS TOut WHERE Brinde IN ('b','c') AND

    NOT EXISTS (

     

    SELECT Codigo FROM tbl AS TInt

    WHERE TOut.Codigo = TInt.Codigo AND TInt.Brinde NOT IN ('b','c'))

     

    GROUP BY Codigo

    HAVING COUNT(DISTINCT Brinde) = 2

     

    -- Consultar os registros que tem somente C

    -- A solução funciona, mas segue uma outra alternativa

    -- O único problema é que é necessário conhecer previamente os brindes

    SELECT Codigo--, [A], [B], [C]

    FROM

    (SELECT Codigo, Brinde FROM tbl) AS TBO

    PIVOT

    (COUNT(Brinde) FOR Brinde IN ([A], [B], [C])) AS TPVT

    WHERE [C] = 1 AND [A] + [B] = 0

     

    [ ]s,

     

    Gustavo

    sexta-feira, 31 de outubro de 2008 22:35
  • Valeu Gustavo.

    Sua resposta resolveu meu problema, obrigado mesmo.

    Abraços.
    segunda-feira, 3 de novembro de 2008 17:05