ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Pesquisa SQL - Delphi
Ir à página 1, 2  Próximo
 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
l.keiner
Novato
Novato


Registrado: Quarta-Feira, 29 de Janeiro de 2020
Mensagens: 12

MensagemEnviada: Qua Jan 29, 2020 11:54 pm    Assunto: Pesquisa SQL - Delphi Responder com Citação

Estou tentando fazer a gerar um relatorio com o seguinte:

Periodo: 01/01/19 a 31/12/19

Saldo Inicial Entrada Saida Saldo de Estoque
codigo | Qtde Entrada Saida Saldo de Estoque
0001 25 10 5 30
0002 05 10 5 10

Estrutura Tabela:
Produto: Codigo, Saldo
Lancamentos: Codigo, qtde, Estado

Na tabela Lancamentos, o campo estado recebe: E(entrada) ou S (Saida)

Conforme vou fazendo lancamentos, vai somando ou diminuindo o saldo da tabela Produto.

O Relatorio consiste em mostrar os produtos , seu saldo inicial, qtde de entradas e saidas e o saldo de estoque, não podendo repetir o codigo.
Teria que pegar o codigo da Tabela de Produtos e buscar as qtdes de entradas ou saidas (podendo ser varias)na tabela lancamentos.
soma e diminui e lista o resultado dos calculos.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qui Jan 30, 2020 9:06 am    Assunto: Responder com Citação

Bom dia,

Estou com algumas dúvidas em relação a estrutura das suas tabelas, mas experimente fazer uns testes mais ou menos dessa forma:

Código:
select
    p.Codigo,
    p.Saldo,
    sum(case when l.Estado = 'E' then l.Qtde else 0 end) as Entrada,
    sum(case when l.Estado = 'S' then l.Qtde else 0 end) as Saida
from Produto as p
inner join Lancamentos as l
    on l.Codigo = p.Codigo
where
    l.Data between :DataIni and :DataFim
group by
    p.Codigo,
    p.Saldo


Espero que ajude


Editado pela última vez por imex em Seg Dez 04, 2023 11:58 am, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
l.keiner
Novato
Novato


Registrado: Quarta-Feira, 29 de Janeiro de 2020
Mensagens: 12

MensagemEnviada: Ter Fev 04, 2020 9:02 pm    Assunto: Responder com Citação

Boa noite

Não era bem isso que precisava...
Ele teria que buscar na tabela Produtos, todos os produtos, pegar da tabela lancamentos e somar os valores de entradas e saidas,

acrescentei agora:
e se possivel, buscar da tabela saldo inicial, buscar pela maior data e pegar o valor do saldo inicial antes dos lancamentos

Talvez esteja montando as tabela erradas...

Tabela Produtos
pro_codigo
pro_saldo

tabela Lancamentos
lan_codigo
lan_situacao
lan_data
lan_qtde
lan_valor_unitario

tabela Saldo Inicial
sal_codigo
sal_data
sal_saldo_inicial

A cada lancamento na tabela Lancamentos, antes de gravar, eu pego o valor do pro_saldo e gravo na tabela saldo inicial

Exemplo na imagem

[img]https://ibb.co/bskK9Yw[/img]
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qua Fev 05, 2020 10:47 am    Assunto: Responder com Citação

Bom dia,

Acredito que a query sugerida deveria retornar a soma das entradas e das saídas.
Segue outra sugestão com a tabela de saldos:

Código:
select
    g.Codigo,
    s.sal_saldo_inicial,
    g.Entrada,
    g.Saida,
    s.sal_saldo_inicial + g.Entrada - g.Saida as saldo_final
from
(
    select
        p.pro_codigo,
        min(lan_data) as data_Inicial,
        sum(case when l.lan_situacao = 'E' then l.lan_qtde else 0 end) as Entrada,
        sum(case when l.lan_situacao = 'S' then l.lan_qtde else 0 end) as Saida
    from Produtos as p
    inner join Lancamentos as l
        on l.lan_codigo = p.pro_codigo
    where
        l.lan_data between :DataIni and :DataFim
    group by
        p.pro_codigo
) as g
inner join SaldoInicial as s
    on s.sal_codigo = g.pro_codigo and s.sal_data = g.data_inicial


Espero que ajude
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
l.keiner
Novato
Novato


Registrado: Quarta-Feira, 29 de Janeiro de 2020
Mensagens: 12

MensagemEnviada: Qua Fev 05, 2020 9:42 pm    Assunto: Pesquisa SQL - DElphi Responder com Citação

Boa Noite

é quase isso...
ele deveria trazer todos os produtos da tabela Produtos, ele só esta trazendo os Produtos que tem lancamentos.

Os produtos podem ou nao ter lancamentos, aquele que não tiver, seria saldo inicial =0.
Conforme a imagem do relatorio em excel.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qui Fev 06, 2020 9:37 am    Assunto: Responder com Citação

Bom dia,

Experimente trocar o join com a tabela Lancamentos de inner para left.

Espero que ajude
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
l.keiner
Novato
Novato


Registrado: Quarta-Feira, 29 de Janeiro de 2020
Mensagens: 12

MensagemEnviada: Qui Fev 06, 2020 9:58 pm    Assunto: Pesquisa SQL - DElphi Responder com Citação

Boa noite

não consigo realizar, sou totalmente leigo em sql, tento alterar o seu codigo mas não consigo ter resultados.

Postei uma imagem [img]https://ibb.co/QJ1mt9Y[/img]
Ele traz assim, mesmo colocando left join não muda nada, pode observar que ele tbm não agrupa por codigo .

ele teria que listar todos os produtos da tabela PRODUTOS, o codigo que não tiver lançamentos trazer null, somar valor de entradas e saidas (campos separados) e trazer o saldo final após os lancamentos.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Sex Fev 07, 2020 10:53 am    Assunto: Responder com Citação

Bom dia,

As quantidades retornadas nas colunas Entrada e Saída estão corretas?
Pode existir mais de um registro na tabela de saldos para o mesmo produto e dia? Se pode, tem como saber qual é o primeiro registro do dia de cada produto?
Qual banco de dados (e versão) você está utilizando?
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
l.keiner
Novato
Novato


Registrado: Quarta-Feira, 29 de Janeiro de 2020
Mensagens: 12

MensagemEnviada: Qui Fev 13, 2020 9:46 pm    Assunto: Pesquisa SQL - DElphi Responder com Citação

Desculpa pela demora no retorno, estava viajando....

As quantidades retornadas nas colunas Entrada e Saída estão corretas?
Sim, porém ele vem repetidos

Pode existir mais de um registro na tabela de saldos para o mesmo produto e dia?
Pode.. Pois você pode dar entrada ou saida do mesmo produto durante o dia

Se pode, tem como saber qual é o primeiro registro do dia de cada produto?
Tem mais de um registro, e estou salvando a data e hora do lançamento

Qual banco de dados (e versão) você está utilizando?
Firebird 3.0
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Sex Fev 14, 2020 4:33 pm    Assunto: Responder com Citação

Então as linhas estão repetidas por existir mais de um registro na tabela saldos para o mesmo produto e dia, e não por causa do agrupamento.
Segue outra sugestão para testes:

Código:
with
    CTE_Agrupa as
    (
        select
            p.pro_codigo,
            min(lan_data) as data_Inicial,
            sum(case when l.lan_situacao = 'E' then l.lan_qtde else 0 end) as Entrada,
            sum(case when l.lan_situacao = 'S' then l.lan_qtde else 0 end) as Saida
        from Produtos as p
        inner join Lancamentos as l
            on l.lan_codigo = p.pro_codigo
        where
            l.lan_data between :DataIni and :DataFim
        group by
            p.pro_codigo
    ),

    CTE_SaldoIni as
    (
        select
            a.*,
            (select first 1 s.sal_saldo_inicial
             from SaldoInicial as s
             where
                 s.sal_codigo = a.pro_codigo and
                 s.sal_data >= a.data_inicial
             order by
                 a.data_inicial) as saldo_inicial
        from CTE_Agrupa as a
    )

select
    pro_codigo,
    saldo_inicial,
    Entrada,
    Saida,
    saldo_inicial + Entrada - Saida as saldo_final
from CTE_SaldoIni


Espero que ajude
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
l.keiner
Novato
Novato


Registrado: Quarta-Feira, 29 de Janeiro de 2020
Mensagens: 12

MensagemEnviada: Qua Fev 19, 2020 9:47 pm    Assunto: Pesquisa SQL - DElphi Responder com Citação

Boa Noite

Seria quase isso, mas o relatorio deve trazer todos os produtos da tabela produtos e aonde não tive lancamentos, trazer 0 ou campo em branco.

https://ibb.co/m6Xb2T0
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qui Fev 20, 2020 10:47 am    Assunto: Responder com Citação

Bom dia,

Segue novamente a sugestão trocando o Inner Join por Left Join:

Código:
with
    CTE_Agrupa as
    (
        select
            p.pro_codigo,
            min(lan_data) as data_Inicial,
            sum(case when l.lan_situacao = 'E' then l.lan_qtde else 0 end) as Entrada,
            sum(case when l.lan_situacao = 'S' then l.lan_qtde else 0 end) as Saida
        from Produtos as p
        left join Lancamentos as l
            on l.lan_codigo = p.pro_codigo
        where
            l.lan_data between :DataIni and :DataFim
        group by
            p.pro_codigo
    ),

    CTE_SaldoIni as
    (
        select
            a.*,
            (select first 1 s.sal_saldo_inicial
             from SaldoInicial as s
             where
                 s.sal_codigo = a.pro_codigo and
                 s.sal_data >= a.data_inicial
             order by
                 a.data_inicial) as saldo_inicial
        from CTE_Agrupa as a
    )

select
    pro_codigo,
    saldo_inicial,
    Entrada,
    Saida,
    saldo_inicial + Entrada - Saida as saldo_final
from CTE_SaldoIni


Espero que ajude
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
l.keiner
Novato
Novato


Registrado: Quarta-Feira, 29 de Janeiro de 2020
Mensagens: 12

MensagemEnviada: Seg Fev 24, 2020 10:18 pm    Assunto: Pesquisa SQL - DElphi Responder com Citação

Boa Noite
Ainda não esta trazendo todo o cadastros de produtos.
Digitei o codigo abaixo na pesquisa da query:

FDQuery1.SQL.Add('with CTE_Agrupa as(');
FDQuery1.SQL.Add('select p.pro_codigo, ');
FDQuery1.SQL.Add('max(lan_data) as data_Inicial,');
FDQuery1.SQL.Add('sum(case when l.lan_situacao = ''E'' then l.lan_qtde else 0 end) as Entrada,' );
FDQuery1.SQL.Add('sum(case when l.lan_situacao = ''S'' then l.lan_qtde else 0 end) as Saida ');
FDQuery1.SQL.Add('from Produtos as p left join Lancamentos as l ');
FDQuery1.SQL.Add('on l.lan_codigo = p.pro_codigo where ');
FDQuery1.SQL.Add('l.lan_data between :DataIni and :DataFim group by p.pro_codigo ');
FDQuery1.ParamByName('DataIni').AsDate := StrToDate('01/01/2020');;
FDQuery1.ParamByName('DataFim').asDate := StrToDate('31/12/2020');
FDQuery1.SQL.Add('), ');
FDQuery1.SQL.Add('CTE_SaldoIni as (');
FDQuery1.SQL.Add('select a.*, (select first 1 s.sal_saldo_inicial from Saldo_Inicial as s ');
FDQuery1.SQL.Add('where s.sal_codigo = a.pro_codigo and s.sal_data >= a.data_inicial ');
FDQuery1.SQL.Add('order by a.data_inicial) as saldo_inicial from CTE_Agrupa as a) ');
FDQuery1.SQL.Add('select pro_codigo, saldo_inicial, Entrada, Saida, saldo_inicial + Entrada - Saida as saldo_final ');
FDQuery1.SQL.Add('from CTE_SaldoIni');
FDQuery1.Active := true;

O resultado esta trazendo conforme esta imagem
[img]https://ibb.co/FDHSDhS[/img]
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qua Fev 26, 2020 9:17 am    Assunto: Responder com Citação

Bom dia,

Experimente essa versão com uma alteração na clausula Where:

Código:
with
    CTE_Agrupa as
    (
        select
            p.pro_codigo,
            min(lan_data) as data_Inicial,
            sum(case when l.lan_situacao = 'E' then l.lan_qtde else 0 end) as Entrada,
            sum(case when l.lan_situacao = 'S' then l.lan_qtde else 0 end) as Saida
        from Produtos as p
        left join Lancamentos as l
            on l.lan_codigo = p.pro_codigo
        where
            (l.lan_codigo is null) or
            (l.lan_data between :DataIni and :DataFim)
        group by
            p.pro_codigo
    ),

    CTE_SaldoIni as
    (
        select
            a.*,
            (select first 1 s.sal_saldo_inicial
             from SaldoInicial as s
             where
                 s.sal_codigo = a.pro_codigo and
                 s.sal_data >= a.data_inicial
             order by
                 a.data_inicial) as saldo_inicial
        from CTE_Agrupa as a
    )

select
    pro_codigo,
    saldo_inicial,
    Entrada,
    Saida,
    saldo_inicial + Entrada - Saida as saldo_final
from CTE_SaldoIni


Espero que ajude
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
l.keiner
Novato
Novato


Registrado: Quarta-Feira, 29 de Janeiro de 2020
Mensagens: 12

MensagemEnviada: Qui Fev 27, 2020 10:14 pm    Assunto: Pesquisa SQL - DElphi Responder com Citação

Boa Noite

Quase....listou todos os produtos da tabela, porém não trouxe os valores.
TIpo, mesmo que não tenha entrada nem saída, deverá listar o valor do campo PRO_Saldo da tabela Produtos.
Ele listou os valores somente dos campos que tiveram alguma entrada ou saida. Imagem abaixo
https://ap.imagensbrasil.org/image/rmmn9m
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi Todos os horários são GMT - 3 Horas
Ir à página 1, 2  Próximo
Página 1 de 2

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB