Usuário com melhor resposta
Consulta unica e exclusiva

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.
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 SnippetCREATE
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 tblWHERE
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
CodigoFROM
tbl AS TOut WHERE Brinde IN ('a','b') ANDNOT
EXISTS (GROUP
BY CodigoHAVING
COUNT(DISTINCT Brinde) = 2-- Consultar os registros que tem somente B e C
-- Utilizar a mesma solução trocando os valores
SELECT
CodigoFROM
tbl AS TOut WHERE Brinde IN ('b','c') ANDNOT
EXISTS (GROUP
BY CodigoHAVING
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 TBOPIVOT
(
COUNT(Brinde) FOR Brinde IN ([A], [B], [C])) AS TPVTWHERE
[C] = 1 AND [A] + [B] = 0[ ]s,
Gustavo
Todas as Respostas
-
-
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'?
-
-
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 SnippetCREATE
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 tblWHERE
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
CodigoFROM
tbl AS TOut WHERE Brinde IN ('a','b') ANDNOT
EXISTS (GROUP
BY CodigoHAVING
COUNT(DISTINCT Brinde) = 2-- Consultar os registros que tem somente B e C
-- Utilizar a mesma solução trocando os valores
SELECT
CodigoFROM
tbl AS TOut WHERE Brinde IN ('b','c') ANDNOT
EXISTS (GROUP
BY CodigoHAVING
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 TBOPIVOT
(
COUNT(Brinde) FOR Brinde IN ([A], [B], [C])) AS TPVTWHERE
[C] = 1 AND [A] + [B] = 0[ ]s,
Gustavo
-