Clipper On Line • Ver Tópico - Select dentro de outro Select

Select dentro de outro Select

Discussão sobre SQL

Moderador: Moderadores

 

Select dentro de outro Select

Mensagempor janio » 06 Mai 2017 20:55

Pessoal,

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

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 de usuário

janio
Colaborador

Colaborador
 
Mensagens: 1835
Data de registro: 06 Jul 2004 07:43
Cidade/Estado: UBAJARA - CE
Curtiu: 8 vezes
Mens.Curtidas: 68 vezes

Select dentro de outro Select

Mensagempor JoséQuintas » 07 Mai 2017 00:46

José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18009
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Select dentro de outro Select

Mensagempor janio » 07 Mai 2017 09:56

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

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 de usuário

janio
Colaborador

Colaborador
 
Mensagens: 1835
Data de registro: 06 Jul 2004 07:43
Cidade/Estado: UBAJARA - CE
Curtiu: 8 vezes
Mens.Curtidas: 68 vezes

Select dentro de outro Select

Mensagempor JoséQuintas » 07 Mai 2017 11:38

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, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18009
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Select dentro de outro Select

Mensagempor janio » 08 Mai 2017 09:25

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 de usuário

janio
Colaborador

Colaborador
 
Mensagens: 1835
Data de registro: 06 Jul 2004 07:43
Cidade/Estado: UBAJARA - CE
Curtiu: 8 vezes
Mens.Curtidas: 68 vezes

Select dentro de outro Select

Mensagempor janio » 09 Mai 2017 00:06

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

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 de usuário

janio
Colaborador

Colaborador
 
Mensagens: 1835
Data de registro: 06 Jul 2004 07:43
Cidade/Estado: UBAJARA - CE
Curtiu: 8 vezes
Mens.Curtidas: 68 vezes

Select dentro de outro Select

Mensagempor janio » 09 Mai 2017 20:23

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

         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 de usuário

janio
Colaborador

Colaborador
 
Mensagens: 1835
Data de registro: 06 Jul 2004 07:43
Cidade/Estado: UBAJARA - CE
Curtiu: 8 vezes
Mens.Curtidas: 68 vezes

Select dentro de outro Select

Mensagempor janio » 11 Set 2017 19:05

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.

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:
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 de usuário

janio
Colaborador

Colaborador
 
Mensagens: 1835
Data de registro: 06 Jul 2004 07:43
Cidade/Estado: UBAJARA - CE
Curtiu: 8 vezes
Mens.Curtidas: 68 vezes

Select dentro de outro Select

Mensagempor janio » 11 Set 2017 19:24

Pessoal,

Seria mais ou menos a Query abaixo!
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 de usuário

janio
Colaborador

Colaborador
 
Mensagens: 1835
Data de registro: 06 Jul 2004 07:43
Cidade/Estado: UBAJARA - CE
Curtiu: 8 vezes
Mens.Curtidas: 68 vezes

Select dentro de outro Select

Mensagempor janio » 11 Set 2017 20:11

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).
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:
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 de usuário

janio
Colaborador

Colaborador
 
Mensagens: 1835
Data de registro: 06 Jul 2004 07:43
Cidade/Estado: UBAJARA - CE
Curtiu: 8 vezes
Mens.Curtidas: 68 vezes

Select dentro de outro Select

Mensagempor JoséQuintas » 11 Set 2017 21:11

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, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18009
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Select dentro de outro Select

Mensagempor janio » 11 Set 2017 23:34

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.

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 de usuário

janio
Colaborador

Colaborador
 
Mensagens: 1835
Data de registro: 06 Jul 2004 07:43
Cidade/Estado: UBAJARA - CE
Curtiu: 8 vezes
Mens.Curtidas: 68 vezes

Select dentro de outro Select

Mensagempor JoséQuintas » 12 Set 2017 09:10

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, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18009
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Select dentro de outro Select

Mensagempor alaminojunior » 10 Jan 2018 10:28

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
Avatar de usuário

alaminojunior
Colaborador

Colaborador
 
Mensagens: 1689
Data de registro: 16 Dez 2005 20:26
Cidade/Estado: Ubatuba - SP
Curtiu: 27 vezes
Mens.Curtidas: 11 vezes




Retornar para SQL

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 6 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro