Select dentro de outro Select

Forum sobre SQL.

Moderador: Moderadores

Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Select dentro de outro Select

Mensagem por janio »

Pessoal,

A consulta abaixo me retornam TODOS os produtos comprados de um determinado fornecedor:

Código: Selecionar todos

SELECT a.codigo, a.descri
FROM a03prd a
INNER JOIN a04dnf b ON ( a.codigo=b.codprd )
WHERE b.CodFrn=50
GROUP BY a.codigo
ORDER BY a.descri
Retorna algo como:
20701 ABS LIVRE ATIVA CLASSIC CA 8 UN
6987 ACHOC ITALAC 200ML
15145 ACHOC ITALAC SC 400G
16462 ACHOC PO MAGICO 200G
...
Com este resultado, agora preciso pegar a ULTIMA COMPRA DE CADA PRODUTO! Como faço?

Janio

PS: tabela de compras a04dnf, campo data datent
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Select dentro de outro Select

Mensagem por JoséQuintas »

José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Select dentro de outro Select

Mensagem por janio »

Quase dando certo...

Com MAX() ele me retorna a ultima data... blz.

Mas os outros dados do SELECT (qtdprd, vlruni, numnot) não são referentes a ultima data. Estranho viu

Código: Selecionar todos

select b.codigo, b.descri, a.qtdprd, a.vlruni, a.numnot, Max(a.datent)
from a04dnf a
inner join a03prd b on (a.codprd=b.CODIGO)
where a.codfrn=3
group by a.codprd
order by b.descri
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Select dentro de outro Select

Mensagem por JoséQuintas »

Normal: o Max() faz retornar a última data, apenas para o campo da data.
Essa vai ser a referência para o outro select.
Lembrando que pode ter mais de uma compra nessa data.
Se for a última, e tiver sequencial de lançamento, talvez seja mais interessante o último lançamento, ou talvez somar os lançamentos dessa última data.

Lembrando que nessa parte ainda sou principiante.
Ainda estou na migração parcial, e por isso esses selects ainda não fazem parte do meu dia-a-dia.
Quem está acostumado provavelmente poderá ter uma solução melhor.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Select dentro de outro Select

Mensagem por janio »

AlxSts, please!

:-o

Tentei tudo ja :(Neg
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Select dentro de outro Select

Mensagem por janio »

Os dados vieram corretos no codigo abaixo, porem, nao sei se eh a forma mais recomendavel... ate pq achei um pouco lento.

Código: Selecionar todos

select a.codprd, a.qtdprd, a.vlruni, a.datent
from a04dnf a
inner join (select max(datent) as data from a04dnf b group by b.codprd) c on c.data = a.datent
where a.codfrn=3
group by a.codprd
order by a.codprd 
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Select dentro de outro Select

Mensagem por janio »

Para conseguir o resultado que eu queria, tive que usar a boa e velha GAMBIARRA!

Ficou muito bom. Rapido. Uma bala

- Listo todos os produtos comprados do fornecedor no periodo
- Organizo com data DECRESCENTE
- Descarto os outros resultado de compras q nao seja a ultima, pegando apenas o primeiro resultado de cada produto

Código: Selecionar todos

			cQuery = "SELECT a.codprd, a.uniprd, a.unicom, a.qtdprd, a.vlruni, a.numnot, a.datent, b.descri, b.sldstk " + ;
			         "FROM a04dnf a " + ;
			         "INNER JOIN a03prd b ON ( a.codprd=b.codigo ) " + ;
			         "WHERE a.is_deleted = 'N' and a.CodFrn='&nCodFrn' and a.datent between '&vDataI_' and '&vDataF_' " + ;
			         "ORDER BY b.descri, a.datent DESC "

			GERA_TAB()
			use &dbftmp as cQuery NEW SCROLLABLE
			DbGoTop()
		
			Do While !Eof()
			
				nCodPrd := CodPrd
				nConta  := 0
				
				Do While nCodPrd = CodPrd
									
					If nConta = 0									
		         	@ PROW() + 01,000 SAY StrZero(CodPrd,5) + " " + Left(DesCri,40)
		         	@ PROW()     ,048 SAY UniCom
		         	@ PROW()     ,051 SAY UniPrd	
			         @ PROW()     ,056 SAY DatEnt
			         @ PROW()     ,069 SAY QtdPrd Pict "@E 99,999.99"
			         @ PROW()     ,083 SAY VlrUni Pict "@E 99,999.99"
			         @ PROW()     ,096 SAY NumNot	         	
		         	@ PROW()     ,123 SAY SldStk Pict "@E 99,999.99"
				      @ PROW() + 01,000 SAY REPLICATE("-",132) 
					Endif
					
	         	nConta++
	
	         	DbSkip()
	         	
	         Enddo
	         
	      Enddo

			Use
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Select dentro de outro Select

Mensagem por janio »

Pessoal,

Estou precisando fazer uma nova consulta que, imagino, também se aplique "select dentro de outro select"!

O negocio é meio complicadim hehehe

Basicamente:
Seleciono os produtos que ENTRARAM num período (isso é facil). Com o resultado dessa Query em maos, agora preciso selecionar quais desses registros (produtos) NÃO TIVERAM vendas no mesmo período.

Código: Selecionar todos

Select distinct a.codigo, a.descri, max(b.DATENT)
from a03prd a
inner join a04dnf b on (a.codigo=b.codprd)
where b.DATEMI between '2016-01-01' and '2016-01-31'
group by a.codigo
order by a.codigo
Resulta:

Código: Selecionar todos

002 ARROZ PARB PAI JOAO 1K 2016-01-13
003 ARROZ PARB PAI JOAO 1K 2016-01-28
016 ARROZ BRANCO GRANEL 1K 2016-01-13
034 MAC NISSIN T MONICA GALINHA 90G 2016-01-19
102 TRIGO D BENTA CF 1K 2016-03-01
Quais desses produtos NAO TIVERAM VENDAS no mesmo período? Eis a questão
Anexos
sql.png
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Select dentro de outro Select

Mensagem por janio »

Pessoal,

Seria mais ou menos a Query abaixo!

Código: Selecionar todos

Select * 
from a04dnf e
where e.datent between '2016-01-01' and '2016-01-31' and
   not exists
	(
	Select null 
	from a03dpd d
	where d.codprd = e.codprd
	)
Todos os produtos que tiveram ENTRADA no período tal, mas que não tem vendas!

A única coisa q ta faltando na query eh informar no select da tabelas de vendas o período que não tenha havido venda. Não é nunca vendeu!. É não vendeu no período que for informado
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Select dentro de outro Select

Mensagem por janio »

Acho q cheguei a um resultado, porem, algo muito interessante esta acontecendo:

Da maneira abaixo a consulta eh instantanea (sem limitação de período na tabela vendas - segundo select).

Código: Selecionar todos

Select distinct e.codprd, b.descri, max(e.datent)
from a04dnf as e
inner join a03prd as b on (b.codigo=e.codprd)
Where e.datent between '2016-01-01' and '2016-01-31' and
   not exists
	(
	Select null
	from a03dpd as t
	where t.codprd = e.codprd
	)
group by e.datent
Se limito o periodo na tabela vendas (segundo select), a consulta demora uma eternidade:

Código: Selecionar todos

Select distinct e.codprd, b.descri, max(e.datent)
from a04dnf as e
inner join a03prd as b on (b.codigo=e.codprd)
Where e.datent between '2016-01-01' and '2016-01-31' and
   not exists
	(
	Select null
	from a03dpd as t
	where t.codprd = e.codprd and t.datemi between '2016-01-01' and '2016-01-31'
	)
group by e.datent
Imaginava que seria exatamente o contrário: Com limitação de data... rapido! Sem limitação de data... lento (já que teoricamente teria que varrer a tabela inteira)
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Select dentro de outro Select

Mensagem por JoséQuintas »

Chute que veio na cabeça...

SELECT item, MAX( datamaxima ) AS data, SUM( qtvenda ) AS total FROM
(
( SELECT item, MAX( dtcompra ) AS datamaxima, 0 AS qtvenda FROM compras GROUP BY item ) AS tempcompras
UNION ALL
( SELECT item, NULL AS datamaxima, COUNT(*) AS qtvenda FROM vendas GROUP BY item ) AS tempvendas
) AS tempcompravenda
GROUP BY item HAVING total = 0

uma seleção de compras
uma seleção de vendas
junta tudo
faz o filtro

De repente pode ser mais rápido, porque vai fazer selects únicos, e não um select pra cada item do select anterior.

Mas como falei, é chute, ainda não faz parte do meu dia a dia fazer essas coisas, então não sei se aceita ou qual o comportamento real.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Select dentro de outro Select

Mensagem por janio »

Quintas, não funcionou!

Mas encontrei uma maneira mais simples que trouxe o resultado desejado e de forma instantanea! Saí de 46 segundos da forma anterior, para instantaneo.

Código: Selecionar todos

Select t.codprd, b. descri
from (Select distinct codprd, datent from a04dnf) as t
left join (select distinct codprd from a03dpd where (datemi between '2016-01-01' and '2016-01-31') c on t.codprd=c.codprd
inner join a03prd as b on (b.codigo=t.codprd)
where (t.datent between '2016-01-01' and '2016-01-31') and (c.codprd is null)
order by b.descri
Todos produtos que tiveram COMPRA no período informado, mas não tiveram VENDA no mesmo período

1. Filtro dos produtos que tiveram compra no período (where (t.datent between '2016-01-01' and '2016-01-31') )
2. Filtro dos produtos que tiveram venda no período (left join)
3. Filtro dos produtos que tiveram compra, mas nao tiveram venda (left join), ou seja, constam na tabela t (a esquerda) e não constam na tabela c (a direita)
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Select dentro de outro Select

Mensagem por JoséQuintas »

legal, pelo menos serviu pra ajudar.
Reduziu o que podiam ser milhares de SELECTs (um por produto), para dois SELECTs.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

Select dentro de outro Select

Mensagem por alaminojunior »

Só refrescando a memória, pois sei que as vezes alguns detalhes passam sem a gente lembrar:

Algumas vezes (ou quase sempre) a demora numa consulta pode ser falta de indexar as colunas que se usam na sentença como parâmetro de busca.
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Responder