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

OldMan
19-07-2007, 22:27
mas tens 2 colunas nessa tabela para inserir os 2 estados?

do genero estado1=0 e estado2=2?

cabiros
19-07-2007, 22:38
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 ................................................

cabiros
19-07-2007, 23:43
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

cabiros
20-07-2007, 00:57
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

cabiros
20-07-2007, 01:37
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

cabiros
20-07-2007, 02:03
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

cabiros
21-07-2007, 14:48
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