Sql fazer junção de dois select ?

18/11/2005

1

Pessoal tenho um tabela chamada entrada e outra venda.
Peciso selecionar na entrada toda a entrada de produtos e todas as saidas na venda assim

Produto entrada saida Saldo
Teste 30 20 10
Tentei fazer assim + não deu certo

With IbQuery1,Sql do
begin
Clear ;
Add(´SELECT Produto,Sum(Quantidade)QuantEntrada FROM ENTRADAS´);
Add(´WHERE Data_Entrada = :VData1´) ;
Add(´GROUP BY PRODUTO´);
Add(´UNION ALL´);
Add(´SELECT Produto, Sum(Quantidade)QuantSaida FROM Vendas´);
Add(´WHERE Data = :VData1´) ;
Add(´GROUP BY PRODUTO´);

ParamByname(´VData1´).AsString :=DateTostr(now) ;
Active:=True ;
end;

Se alguem sabe com fazer esta Sql, e puder me ajudar.

Obrigado a tds !!


Responder

Posts

18/11/2005

Thomaz_prg

tenta aí:

SELECT
E.PRODUTO,
SUM(E.QUANTIDADE) AS QTD_ENTRADA,
SUM(V.QUANTIDADE) AS QTD_SAIDA
FROM
ENTRADAS E
FULL OUTER JOIN VENDAS V ON
(V.PRODUTO = E.PRODUTO AND V.DATA = :VDATA1)
WHERE
E.DATA = :VDATA1


Mas que banco você tá usando?? E que erro tá dando na sua instrição anterior??


Responder

18/11/2005

Essistemas

É isto mesmo, só que quando faço a entrada de um
no campo Entrada ela me retorna 1 até ai tudo certo mas quando vendo ou seja faço a saida o campo Entrada retorna o mesmo do campo Saida
Exemplo Entrei e saida, Sendo que a entrada deverira ser um
3 3

Acredito ser apenas maus um detalhe. Eu estou usando Firebird.
Muito Obrigado !!


Responder

20/11/2005

Essistemas

With IbQuery1,Sql do
begin
Clear ;
Add(´SELECT A.PRODUTO,SUM(A.QUANTIDADE),´);
Add(´A.PRODUTO,SUM(B.QUANTIDADE)´);
Add(´FROM ENTRADAS A, VENDAS B´);
Add(´GROUP BY A.PRODUTO,B.PRODUTO´);
Active:=True ;
end;
end;

Consegui assim tambem + preciso pegar a somatoria de cada tabela separado, ele esta somandado saida e entrada juntos. Eu Preciso de saber as entrada e saidas separadas !!, Se puder me ajudar a concluir !!


Responder
with IbQuery1.Sql do
begin
  Clear;
  Add(´select´);
  Add(´  p.produto,´);
  Add(´  (select sum(e.quandidade)´);
  Add(´   from entradas e´);
  Add(´   where e.produto = p.produto) entradas,´);
  Add(´  (select sum(v.quandidade)´);
  Add(´   from vendas v´);
  Add(´   where v.produto = p.produto) saidas´);
  Add(´from´);
  Add(´  produto p´);
  Open;
end;


se quiser um determinado período:
with IbQuery1.Sql do
begin
  Clear;
  Add(´select´);
  Add(´  p.produto,´);
  Add(´  (select sum(e.quandidade)´);
  Add(´   from entradas e´);
  Add(´   where e.produto = p.produto´);
  Add(´     and e.data_entrada between :dataini and :datafim) entradas,´);
  Add(´  (select sum(v.quandidade)´);
  Add(´   from vendas v´);
  Add(´   where v.produto = p.produto´);
  Add(´     and v.data between :dataini and :datafim) saidas´);
  Add(´from´);
  Add(´  produto p´);
  ParamByName(´dataini´).asdatetime := datainicial;
  ParamByName(´datafim´).asdatetime := datafinal;
  Open;
end;



Responder

20/11/2005

Essistemas

Emerson valeu mesmo é isso mesmo,
só mais uma pergunta nesta Sql mesmo tenho a coluna entrada, Saida
tem como eu criar mais a coluna saldo que seria Entrada - Saida, ficaria perfeito. Obrigado !!! :lol:


Responder
se você está fazendo isso pelo Delphi, eu sugiro que o campo [i:654f5480d0]saldo[/i:654f5480d0] seja um campo calculado. assim a performance será maior, pois o dataset conseguiria trabalhar com os valores de entrada e saída já somados.

se quiser trazer o saldo pela instrução sql, as somas deverão ser refeitas para o campo saldo, o que acarretará em perda de performance:

with IbQuery1.Sql do 
begin 
  Clear; 
  Add(´select´); 
  Add(´  p.produto,´); 
  Add(´  (select sum(e.quandidade)´); 
  Add(´   from entradas e´); 
  Add(´   where e.produto = p.produto) entradas,´); 
  Add(´  (select sum(v.quandidade)´); 
  Add(´   from vendas v´); 
  Add(´   where v.produto = p.produto) saidas,´); 

  Add(´  (select sum(e.quandidade)´); 
  Add(´   from entradas e´); 
  Add(´   where e.produto = p.produto) - ´); 
  Add(´  (select sum(v.quandidade)´); 
  Add(´   from vendas v´); 
  Add(´   where v.produto = p.produto) saldo´); 

  Add(´from´); 
  Add(´  produto p´); 
  Open; 
end;


ou:
with IbQuery1.Sql do 
begin 
  Clear; 
  Add(´select´); 
  Add(´  p.produto,´); 
  Add(´  (select sum(e.quandidade)´); 
  Add(´   from entradas e´); 
  Add(´   where e.produto = p.produto´); 
  Add(´     and e.data_entrada between :dataini and :datafim) entradas,´); 
  Add(´  (select sum(v.quandidade)´); 
  Add(´   from vendas v´); 
  Add(´   where v.produto = p.produto´); 
  Add(´     and v.data between :dataini and :datafim) saidas,´); 

  Add(´  (select sum(e.quandidade)´); 
  Add(´   from entradas e´); 
  Add(´   where e.produto = p.produto´); 
  Add(´     and e.data_entrada between :dataini and :datafim) - ´); 
  Add(´  (select sum(v.quandidade)´); 
  Add(´   from vendas v´); 
  Add(´   where v.produto = p.produto´); 
  Add(´     and v.data between :dataini and :datafim) saldo´);

  Add(´from´); 
  Add(´  produto p´); 
  ParamByName(´dataini´).asdatetime := datainicial; 
  ParamByName(´datafim´).asdatetime := datafinal; 
  Open; 
end;



Responder

21/11/2005

Essistemas

Emerson, nunca trabalhei com campo campo calculado, como eu faria neste caso para trabalhar neste caso, agredecendo sua boa vontande em ajudar, uma outra questão é esta sql só busca se existir movimento de saida tambem, eu precisaria movimentos independentes, se tiver saida ele mostra saida e entrada 0 se tiver só entrada ele mostra entrada e saida 0 intendeu, e que estou fazendo um mapa de movimentação de produtos .
Fiz uma modificação e inclui a pesquisa na tabela de produtos, p/ trazer o estoque do produto no momento

With ObjVendas.Tb_Vendas,sql do
begin
Clear;
Add(´select´);
Add(´P.produto,´);
Add(´(select sum(e.quantidade)´);
Add(´from entradas e´);
Add(´where e.produto = P.produto´);
Add(´and e.data_entrada between :dataini and :datafim) entradas,´);
Add(´(select sum(v.quantidade)´);
Add(´from vendas v´);
Add(´where v.produto = P.produto´);
Add(´and v.data between :dataini and :datafim) saidas,´);
Add(´(select sum(x.quantidade)´);
Add(´from Produtos x´);
Add(´where x.produto = P.produto) Estoque´);
Add(´from´);
Add(´ VENDAS p´);
Add(´Group by P.Produto´) ;
ParamByName(´dataini´).asString := Data1.Text;
ParamByName(´datafim´).asString := Data2.Text;
Open;
end;


Responder
Preste atenção nas dicas que lhe são passadas. Em nenhum dos exemplos a tabela principal é VENDAS, como você transcreveu.
A tabela principal para consulta é PRODUTOS. Isso porque, de outra forma, vai acontecer o que você notou: serão trazidos somente produtos que tenham sofrido alguma venda.

no caso do campo calculado é bem simples.
supondo que seus campos já tenham sido ´persistidos´, crie um novo campo do tipo calculado:
dê um duplo-clique no seu dataset e pressione CTRL+N (New Field).
Field Name: SALDO
Type: Float
Field Type: Calculated

Agora, no evento OnCalcFields do dataset, faça assim:
SeuDatasetSALDO.AsFloat := SeuDatasetENTRADAS.AsFloat - SeuDatasetSAIDAS.AsFloat;

Pronto! Ao exibir os campos numa grade, por exemplo, os valores aparecerão como desejado.


Responder

23/11/2005

Essistemas

Emerson Obigado pela ajuda, tenho procurado ficar atento as dicas, como meu conhecimento em sql é pouco fica um pouco complicado. + se no final eu sugerir a tabela produtos como esta no exemplo
Add(´from´);
Add(´ produto p´); ele me traz todos os produtos da tabela produtos
e não aceita agruprar. Se eu colocar no final tabela Vendas ele me traz na quela situação que te passei e a agrupa normal, será que esta faltando ainda algum detalhe.
Obrigado !!


with IbQuery1.Sql do
begin
Clear;
Add(´select´);
Add(´ p.produto,´);
Add(´ (select sum(e.quandidade)´);
Add(´ from entradas e´);
Add(´ where e.produto = p.produto´);
Add(´ and e.data_entrada between :dataini and :datafim) entradas,´);
Add(´ (select sum(v.quandidade)´);
Add(´ from vendas v´);
Add(´ where v.produto = p.produto´);
Add(´ and v.data between :dataini and :datafim) saidas,´);

Add(´ (select sum(e.quandidade)´);
Add(´ from entradas e´);
Add(´ where e.produto = p.produto´);
Add(´ and e.data_entrada between :dataini and :datafim) - ´);
Add(´ (select sum(v.quandidade)´);
Add(´ from vendas v´);
Add(´ where v.produto = p.produto´);
Add(´ and v.data between :dataini and :datafim) saldo´);

Add(´from´);
Add(´ produto p´);
ParamByName(´dataini´).asdatetime := datainicial;
ParamByName(´datafim´).asdatetime := datafinal;
Open;
end;


Responder
desculpe, não é uma bronca... é que às vezes passamos as dicas de um jeito e os colegas copiam faltando algo, ou esquecendo de uma condição. o que eu quis dizer foi somente um ´fique atento´ se copiou a instrução corretamente. desculpe se me fiz parecer rude. :(

quanto à sua última mensagem, eu não entendi o que você quis dizer com
´se no final eu sugerir a tabela produtos como esta no exemplo
Add(´from´);
Add(´ produto p´);
ele me traz todos os produtos da tabela produtos e não aceita agruprar´
eu não entendi o porque do agrupamento. a sua tabela produtos é o cadastros de produtos, com um registro pra cada produto, certo?
se sim, não é necessário agrupamento. serão calculados os totais para cada produto, não havendo necessidade de agrupamento, pois o sub-select já trará os valores ´agrupados´.

talvez eu não tenha endendido corretamente a sua dúvida.


Responder

24/11/2005

Essistemas

Não que isso Emerson, não passou está impressão não é o seguinte.
Tenho uma tabela a onde são cadastrado todos os produtos certo.
Tenho uma tabela a onde são registrado todas as vendas que se chama vendas mesmo, tenho uma tabela de entrada que se chama entradas.

Então eu preciso pegar os totais de todas a entradas e todas as saidas de um produto.

No exemplo que vc me passou no final do from ele faz select produto p, se deu deixar deste jeito ele traz para minha todo o meu cadastro de produto intendeu, Agora seu eu mudar esta ultima linha ]
from
Produtos p
Para From Vendas P
ai da certo, + cai naquela se nãi tiver venda ele não mostra a entrada tambem.

E quando mudo para from vendas eu tenho que fazer o seguinte
Group by Produto.P se não ele me traz os itens de forma desagrupada

Clear;
Add(´select´);
Add(´p.produto,´);
Add(´(select sum(e.quantidade)´);
Add(´from entradas e´);
Add(´where e.produto = p.produto´);
Add(´and e.data_entrada >= :dataini and e.data_entrada <=:datafim) entradas,´);
Add(´(select sum(v.quantidade)´);
Add(´from vendas v´);
Add(´where v.produto = p.produto´);
Add(´and v.data >= :dataini and v.data <=:datafim) saidas´);
Add(´from´);
Add(´Vendas p´);
Add(´Group by p.Produto´);
ParamByName(´dataini´).asString := Data1.Text;
ParamByName(´datafim´).asString := Data2.Text;
Open;

Obigado !!


Responder
certo... então tentemos diferente. para isso será necessário criar um view:
create view vw_movimentacao (produto, entrada, saida, data)
as
select
  produto, quantidade, cast(0 as numeric(10,2)) saida, data_entrada
from
  entradas
union all
select
  produto, cast(0 as numeric(10,2)) entrada, quantidade, data
from
  vendas


depois da view criada, poderemos utilizá-la assim:
select
  produto, sum(entrada) entrada, sum(saida) saida
from
  vw_movimentacao
where
  data between :dataini and :datafim
group by
  produto



Responder

02/12/2005

Amarildo

Ola Emerson, estou tendo uma dificuldade quase parecida, somente uso um banco de dados (paradox) para gerenciar as entradas e saidas onde uso um campo identificador como situacao = ´E´ ou ´S´ OU ´D´ e gostaria de proceder conforme descrito no exemplo no qual tens feito, so que nao estou conseguindo descrever as funcionabilidades para que quando for uma destas situacoes a query busque se for E OU D acesse a tabela do cliente e quando for E a tabela do fornecedor, tenho tentado de varias formas possivel e tens ocorrido alguns erros, gostaria que em cima deste exemplo noqual tens ajudado o amigo poderia descrever como faço para encaixar minha duvida, obrg pela atenção no aguardo por maiores informacoes.


Responder
certo, mas o que exatamente você quer exibir.
passe um exemplo mostrando a estrutura das suas tabelas (somente os campos pertinentes) e o resultado que você deseja obter.


Responder

02/12/2005

Amarildo

Emerson, vou passar uma rotina na qual tentei montar e nada de funcionar creio que para voce seja fácil;

select lanctos.*, cadcli.cli_nome, cadfor.for_nome from lanctos, cadcli, cadfor
where
(lanctos.lct_operacao = ´E´ then
acesse o banco de dados dos fornecedores e traga o nome do fornec
sum(lanctosl.lct_quantidade * lct_preco) as totalentradas),

(lanctos.lct_operacao = ´S´ then
acesse o banco de dados CLIENTES e traga o nome do CLIENTE
sum(lanctosl.lct_quantidade * lct_preco) as totalSAIDAS),

(lanctos.lct_operacao = ´D´ then
acesse o banco de dados CLIENTES e traga o nome do CLIENTE
sum(lanctosl.lct_quantidade * lct_preco) as totalDEVOLUCAO)



Estou usando delphi 5 com base de dados paradox

NO AGUARDO POR MAIORES INFORMACOES


Responder