View Full Version : select sql
alfinete 19-07-2007, 22:16 tenho uma tabela em que cada resisto tem n estados
o mesmo resgisto pode ter estado=0 e estado =2
notas, pode haver 5 estados possiveis
eu quero fazer um select que so fassa o select dos registos que so e apenas tem estado=0, ou seja os resgistos que tenham 2 ou mais estados simultaneamente não podem aparecer
deem o exemplo assim
select * form tab
where ..........................
gostava de uma ajuda
mas tens 2 colunas nessa tabela para inserir os 2 estados?
do genero estado1=0 e estado2=2?
select * from tab where estado = 0
Não me parece que seja esta a tua duvida
Gostaria que colocasses o código da criação da tabela para te poder ajudar
SoundSurfer 19-07-2007, 23:03 SELECT * FROM
(
SELECT [chave e colunas relevantes excepto estado], SUM(estado) as soma FROM [tabela]
GROUP BY [chave e colunas relevantes excepto estado]
)
WHERE soma = 0
alfinete 19-07-2007, 23:09 só tenho uma coluna nomeada estado , que guarda os varios estados existentes
do tipo :
caso1 :
tenho o pedido com dados x , com estado = 0 e id=0,
e mesmo pedido com os mesmos dados x , estado=1 e id =2
caso2 :
tenho o pedido com dados x , com estado = 0 e id=0,
e mesmo pedido com os mesmos dados x , estado=1 e id =2
e mesmo pedido com os mesmos dados x , estado=2 e id =3
caso 2 :
tenho o pedido com dados x , com estado = 0 e id=0,
o pedido do caso 1 e 2 não deve mostrar
o do caso 3 deve mostrar
é do tipo isto que quero, so mostrar os registos que so tem apenas estado =0
do tipo a tabela tem id_util,id_prod,datahora,quantidade,utilizador, estado
estado pode ser 0/1/2/3/4
alfinete 19-07-2007, 23:15 este é o meu select sem a clausula where
SELECT TabUtilizador.Nome, TabPedido.DataHora, TabPedido.Quantidade, TabProduto.Nome, TabProduto.Stock
FROM TabUtilizador INNER JOIN
TabPedido ON TabUtilizador.Id = TabPedido.IdUtilizador INNER JOIN
TabProduto ON TabPedido.IdProduto = TabProduto.Id
where ................................................
Não gosto de INNER JOIN
É mais simples assim.
SELECT TabUtilizador.Nome, TabPedido.DataHora, TabPedido.Quantidade, TabProduto.Nome, TabProduto.Stock
FROM TabUtilizador, TabPedido, TabProduto where TabUtilizador.Id = TabPedido.IdUtilizador
and TabPedido.IdProduto = TabProduto.Id
and Tabpedido.Estado = 0
Supus que a coluna estado estive-se na Tabpedido
Não fica mais simples de perceber?
Mas nem sempre podes usar, como por exemplo em LEFT OUTER JOIN
alfinete 20-07-2007, 00:04 não dá na mesma
pois assim mostra tdos os pedidos que tem estado =0 , tdo bem, mas se esse pedido ao mesmo tempo tiver estado= 1 mostra na mesma e neste caso eu não queria que mostrasse esse registo
obrigado na mesma
SELECT TabUtilizador.Nome, TabPedido.DataHora, TabPedido.Quantidade, TabProduto.Nome, TabProduto.Stock
FROM TabUtilizador, TabPedido, TabProduto where TabUtilizador.Id = TabPedido.IdUtilizador
and TabPedido.IdProduto = TabProduto.Id
and Tabpedido.Estado = 0
e se acrecentares um
and not exists (SELECT TabUtilizador.Nome, TabPedido.DataHora, TabPedido.Quantidade, TabProduto.Nome, TabProduto.Stock
FROM TabUtilizador, TabPedido, TabProduto where TabUtilizador.Id = TabPedido.IdUtilizador
and TabPedido.IdProduto = TabProduto.Id
and Tabpedido.Estado != 0)
sera que da erro? se der espero que tenhas percebido o raciocinio ;)
experimenta em vez de NOT existe mete NOT IN
se tiveres com MS sql server tem o except
SELECT TabUtilizador.Nome, TabPedido.DataHora, TabPedido.Quantidade, TabProduto.Nome, TabProduto.Stock
FROM TabUtilizador, TabPedido, TabProduto where TabUtilizador.Id = TabPedido.IdUtilizador
and TabPedido.IdProduto = TabProduto.Id
and Tabpedido.Estado = 0
except
(SELECT TabUtilizador.Nome, TabPedido.DataHora, TabPedido.Quantidade, TabProduto.Nome, TabProduto.Stock
FROM TabUtilizador, TabPedido, TabProduto where TabUtilizador.Id = TabPedido.IdUtilizador
and TabPedido.IdProduto = TabProduto.Id
and Tabpedido.Estado != 0)
alfinete 20-07-2007, 01:31 com not exists não mostra nehum registo, nem os que tem so estado =0
com o except
dá este erro
Incorrect syntax near the keyword 'except'.
isto no sqlserver2000
Pois é provável que só funcione no 2005.
experimenta o NOT IN
O mal é teres isso na mesma tabela onde se encontram os dados
alfinete 20-07-2007, 01:56 a imagem dos registos da tabela
http://img165.imageshack.us/img165/7882/tabpedidoma9.th.jpg (http://img165.imageshack.us/my.php?image=tabpedidoma9.jpg)
vendo a imagem temos 4 registos
com codigo 12,13,18,19 respecticamente
como devem ter reparado o registo 18,19 são iguais so varia o estado
na minha pesquiza devido ao 18,19, serem o mesmo(e ter mais que um estado) , so quero mostrar o 12 e o 13
Esquece o que escrevi que ias ter na mesma o mesmo problema
experimenta
SELECT TabUtilizador.Nome, TabPedido.DataHora, TabPedido.Quantidade, TabProduto.Nome, TabProduto.Stock
FROM TabUtilizador, TabPedido, TabProduto where TabUtilizador.Id = TabPedido.IdUtilizador
and TabPedido.IdProduto = TabProduto.Id
and Tabpedido.Estado = 0 and not tabpedido.estado !=0
alfinete 20-07-2007, 02:09 se esqueço o not in como ficamos.
AliFromCairo 20-07-2007, 05:53 Penso que a solução que o SoundSurfer sugeriu funciona, embora ele na altura não tivesse todos os dados necessários.
Segue outra versão (usei o AS para não tornar a query muito verbosa):
SELECT u.Nome, pe.DataHora, pe.Quantidade, pr.Nome, pr.Stock
FROM TabUtilizador AS u INNER JOIN TabPedido AS pe ON u.Id = pe.IdUtilizador
INNER JOIN TabProduto AS pr ON pe.IdProduto = pr.Id
GROUP BY pe.IdUtilizador, pe.IdProduto, pe.Quantidade, pe.DataHora
HAVING SUM(estado) = 0;
Alternativamente, podias usar uma subquery correlacionada (http://dev.mysql.com/doc/mysql/en/correlated-subqueries.html), mas a query ficaria bastante maior. No entanto, caso o teu estado deixe de ser um tipo numérico e passe a ser texto, esta solução pode ser viável.
alfinete 20-07-2007, 22:13 agradeço as voças ajudas
mas não consegui resolver o prob , mas aqui vai uma explicação julgo eu melhor.
resumindo
imagem da bd que tenho
http://img522.imageshack.us/img522/8207/bdvh2.th.jpg (http://img522.imageshack.us/my.php?image=bdvh2.jpg)
os campos que quero seleccionar são os que estão na imagem dos registos da BD
vistos a baixo
http://img165.imageshack.us/my.php?image=tabpedidoma9.jpg
fazemdo assim
SELECT TabUtilizador.Nome, TabPedido.DataHora, TabPedido.Quantidade, TabProduto.Nome, TabProduto.Stock
FROM TabUtilizador INNER JOIN
TabPedido ON TabUtilizador.Id = TabPedido.IdUtilizador INNER JOIN
TabProduto ON TabPedido.IdProduto = TabProduto.Id
where TabPedido.estado=0
com este code ele mostrame os registos 12,13,18
mas como o 18 e o 19 são o mesmo pedido mas com estado diferente
eu so quero mostrar o 12 e o 13
espero que assim ajude mais
obrigado
AliFromCairo 20-07-2007, 22:26 Experimentaste o código que coloquei em cima? E não mostra só os registos que queres?
alfinete 20-07-2007, 22:39 experimentei a solução do AliFromCairo (http://www.techzonept.com/member.php?u=62945), mas não dá nada, dá erros
obrigado na mesma
AliFromCairo 20-07-2007, 22:41 Podes indicar quais foram os erros pf.
alfinete 20-07-2007, 22:55 o erro é este
Server: Msg 8120, Level 16, State 1, Line 7
Column 'u.Nome' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Server: Msg 8120, Level 16, State 1, Line 7
Column 'pr.Nome' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Server: Msg 8120, Level 16, State 1, Line 7
Column 'pr.Stock' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
AliFromCairo 20-07-2007, 23:00 Hmm.. Experimenta colocar esses campos na cláusula GROUP BY:
SELECT u.Nome, pe.DataHora, pe.Quantidade, pr.Nome, pr.Stock
FROM TabUtilizador AS u INNER JOIN TabPedido AS pe ON u.Id = pe.IdUtilizador
INNER JOIN TabProduto AS pr ON pe.IdProduto = pr.Id
GROUP BY u.Nome, pr.Nome, pr.Stock, pe.IdUtilizador, pe.IdProduto, pe.Quantidade, pe.DataHora
HAVING SUM(estado) = 0;
alfinete 20-07-2007, 23:06 agra ja faz o select, mas mostra um reg a mais do que devia mostrar
ou seja mostra o registo com codigo 18, que não devia mostrar, ou seja so devia mostrar os
registos com codigo 12,13
se conseguisses arranjar uma solução , agradecia
obrigado na mesma
AliFromCairo 20-07-2007, 23:26 8|
Bom, experimenta esta:
SELECT u.Nome, pe1.DataHora, pe1.Quantidade, pr.Nome, pr.Stock
FROM TabUtilizador AS u INNER JOIN TabPedido AS pe1 ON u.Id = pe1.IdUtilizador
INNER JOIN TabProduto AS pr ON pe1.IdProduto = pr.Id
WHERE NOT EXISTS (SELECT *
FROM TabPedido AS pe2
WHERE pe1.IdUtilizador = pe2.IdUtilizador AND pe1.IdProduto = pe2.IdProduto AND
pe1.DataHora = pe2.DataHora AND pe1.Quantidade = pe2.Quantidade AND
pe1.Obs = pe2.Obs AND pe1.Codigo != pe2.Codigo AND pe1.Estado != pe2.Estado) AND pe1.estado = 0;
alfinete 20-07-2007, 23:41 mostra bem o 12 e o 13,mas duplica o 18 que eu nam quero que apareça
AliFromCairo 21-07-2007, 01:58 Experimentei criar as tabelas e preenchê-las com os valores que tens num dos screenshots. As queries funcionam no MySQL, a única razão que vejo para isso dar resultados diferentes no SQL Server é a maneira como uma coluna com o "valor" NULL é manipulado.
Experimenta eliminar, temporariamente, a coluna Obs da tabela TabPedido (suponho que tenha o "valor" NULL por defeito) e executar as queries acima, com as devidas alterações, ou seja, remover o campo Obs.
De qualquer forma segue outra versão de forma a suportar o NULL:
SELECT u.Nome, pe1.DataHora, pe1.Quantidade, pr.Nome, pr.Stock
FROM TabUtilizador AS u INNER JOIN TabPedido AS pe1 ON u.Id = pe1.IdUtilizador
INNER JOIN TabProduto AS pr ON pe1.IdProduto = pr.Id
WHERE NOT EXISTS (SELECT *
FROM TabPedido AS pe2
WHERE pe1.IdUtilizador = pe2.IdUtilizador AND pe1.IdProduto = pe2.IdProduto AND
pe1.DataHora = pe2.DataHora AND pe1.Quantidade = pe2.Quantidade AND
(pe1.Obs = pe2.Obs OR pe1.Obs IS NULL AND pe2.Obs IS NULL) AND
pe1.codigo != pe2.Codigo AND pe1.Estado != pe2.Estado) AND pe1.Estado = 0;
Depois diz qualquer coisa.
alfinete 21-07-2007, 02:33 pesso desculpa por tdo este incoodo mas com a vossa ajuda , a minha e a de um colega meu resolvemos isto assim,
onde na tabela de pedidos temos 2 pedidos iguais com codigo18 e 19 respectivamente, como esse é o mesmo pedido e so muda a datahora e o estado (devido a ser o mesmo pedido), ficam os dois com mesmo id ou seja 18.
logo assim ficou o sql .
SELECT TabUtilizador.Nome, TabPedido.DataHora, TabPedido.Quantidade, TabProduto.Nome, TabProduto.Stock
FROM TabUtilizador INNER JOIN
TabPedido ON TabUtilizador.Id = TabPedido.IdUtilizador INNER JOIN
TabProduto ON TabPedido.IdProduto = TabProduto.Id
WHERE (Estado = 0) AND (Codigo IN
(SELECT Codigo
FROM TabPedido
GROUP BY Codigo
HAVING (COUNT(Codigo) = 1)))
obrigado por tdos os help's
problema resolvidissimo
Finalmente :)
Já estava a dar luta lol
:-D
alfinete 22-07-2007, 17:10 realmente ha coisa lixadas que as vezes parecem faceis
brigado por tdo e a tdos
|
|