Ajuda com select em sql server

28 respostas Resolvido
sqlserver
V

Bom dia pessoal preciso fazer um relatório onde apresenta as entradas e saidas de produtos e matéria-prima. Na tabela as entradas e saidas ficam na mesma coluna, o que difere é uma segunda coluna onde determina o tipo. Consigo trazer a lista de itens com as saidas, mas nao estou conseguindo trazer as entradas junto.

Alguém pode me dar um auxilio? estou aprendendo sql ainda.
Abaixo segue exemplo.

** tipos de movimento **

L - saida
P - entrada
C - saida
A - entrada
B - saida
E - entrada

SELECT
	e1.cd_material,
	SUM(e1.quantidade) AS saidas
FROM
	esmovime e1
WHERE
	(e1.cd_esp_estoque = 'L' OR e1.cd_esp_estoque = 'C' OR e1.cd_esp_estoque = 'B')
	AND e1.dt_movimento = '2019-02-14'
GROUP BY
	e1.cd_material

Preciso adicionar a coluna com a soma das entradas que sao tipos P, A e E

28 Respostas

L

Se vc quer retornar a soma das quantidades de entradas:

SELECT
	e1.cd_esp_estoque AS tipoMovimento,
	SUM(e1.quantidade) AS saidas
FROM
	esmovime e1
WHERE
	e1.cd_esp_estoque IN ('P', 'A', 'E')
	AND e1.dt_movimento = '2019-02-14'
GROUP BY
	e1.cd_esp_estoque
V

oi Lucas, mas preciso trazer as entradas e as saídas, tipo material | saidas | entradas

D

Particularmente, não gosto desta abordagem. É de difícil manutenção.
A melhor opção, no meu ponto de vista, é fazer um select que traga tudo e tratar no código, infelizmente.

L

Veja se funciona, já fiz algo semelhante no oracle e funcionou:

SELECT
	m.tipo as tipoMovimento,
	SUM(m.quantidade) AS quantidade
FROM
	(
		SELECT 'entradas' AS tipo, e.quantidade AS quantidade, e.dt_movimento FROM esmovime e WHERE e.cd_esp_estoque IN ('P', 'A', 'E')
		UNION
		SELECT 'saidas' AS tipo, s.quantidade AS quantidade, s.dt_movimento FROM esmovime s WHERE s.cd_esp_estoque IN ('L', 'C', 'B')
	) m
WHERE
	m.dt_movimento = '2019-02-14'
GROUP BY
	m.tipo
V

Oi Lucas ainda não foi… retirei o ultimo and perto da data, mas acusa que nao existe m.Dt_movimento

L

Foi mals, tem q retornar o dt movimento nos selects do from. Alterei a query, testa ai

V

Agora foi quase… rsrs mas me retornou somente a soma de tudo, preciso que veio item a item entende? tipo

item x - saida 10 - entrada 5
item y - saida 1 - entrada 45

V

Lucas, consegui! ajustei o modelo que voce me enviou e deu certo!! Cara muito obrigado mesmo!

L

Pow mano, manda ai como ficou. Queria ver, ainda mais depois da ajuda uai. =)

Tinha montado essa query aqui:

SELECT
	m.cd_material as material,
	e.quantidade AS "entradas",
	s.quantidade AS "saidas"
FROM
	esmovime m
	LEFT JOIN (
		SELECT e.cd_material, SUM(e.quantidade) AS quantidade 
		FROM esmovime e 
		WHERE e.cd_material = m.cd_material 
		AND e.cd_esp_estoque IN ('P', 'A', 'E')
	) e ON e.cd_material = m.cd_material
	LEFT JOIN (
		SELECT s.cd_material, SUM(s.quantidade) AS quantidade 
		FROM esmovime s 
		WHERE s.cd_material = m.cd_material 
		AND s.cd_esp_estoque IN ('L', 'C', 'B')
	) s ON s.cd_material = m.cd_material
WHERE
	m.dt_movimento = '2019-02-14'
V

Cara, ficou igualzinho o seu rsrs, mas acho que ainda precisar mexer, está ficando assim o resultado:

1Z86154212 saida 10
1Z86154212 entrada 7
mas o correto seria ficar tudo na mesma linha entende, tipo

1Z86154212 saida 10 entrada 7

L

O resultado da consulta q montei deve ter retornar algo assim:

| material | entradas | saidas |
+----------+----------+--------+
|        1 |       10 |     10 |
+----------+----------+--------+
|        2 |       20 |     20 |
+----------+----------+--------+
|        3 |       30 |     30 |
+----------+----------+--------+

Não serve não?

Pq se vc realmente precisa do texto antes da soma, basta adicionar no select:

m.cd_material as material,
'entrada' AS "entrada_label",
e.quantidade AS "entradas",
'saida' AS "saida_label",
s.quantidade AS "saidas"

ou vc pode concatenar:

m.cd_material as material,
'entrada ' || e.quantidade AS "entradas",
'saida ' || s.quantidade AS "saidas"
V

kkk, to mais perdido que bolacha em boca de véio… fiz assim:

1. *     SELECT
2. *     	m.Cd_material as material, 
3. *     	SUM(m.entradas) AS entradas, SUM(m.saidas) AS saidas
4. *     FROM
5. *     	(
6. *     		SELECT 'entradas' AS tipo, e.Cd_material, e.quantidade AS entradas, e.dt_movimento FROM esmovime e WHERE e.cd_esp_estoque IN ('P', 'A', 'E')
7. *     		UNION
8. *     		SELECT 'saidas' AS tipo, s.Cd_material, s.quantidade AS saidas, s.dt_movimento FROM esmovime s WHERE s.cd_esp_estoque IN ('L', 'C', 'B')
9. *     	) m
10. *     WHERE
11. *     	m.dt_movimento = '2019-02-14'
12. *     GROUP BY
13. *     	m.tipo, m.Cd_material order by Cd_material asc

mas ele diz que a coluna saida nao existe.

L

Esse erro eh pq os 2 selects tem q ter as mesmas colunas, e da forma como vc colocou, um retorna o alis “entradas” e o outro retorna “saidas”.

Mas eu acho q o select q montei retorna do jeito q vc precisa viu (bom, pelo menos pelo que entendi). Até coloquei o exemplo do retorno, dá uma olhada pra ver se eh isso msm)

V

Pois é tentei rodar o seu exemplo mas ele dá a mensagem m.Cd_material could be not bound. Nao achei jeito de ajustar

L

cd_material não é uma coluna de esmovime ?

V

sim, isso que é estranho

D

A melhor solução é adaptar a sugestão do @Lucas_Camara

Provavelmente, usando OUTER LEFT.
Fiz algo nesse sentido há quase 10 anos atrás… Precisava de uma query que retornasse registros em que a mesma coluna tivesse valores diferentes…

L

Tenta assim:

SELECT
	m.cd_material AS material,
	e.quantidade AS "entradas",
	s.quantidade AS "saidas"
FROM
	esmovime m
	LEFT JOIN (
		SELECT e.cd_material as material, SUM(e.quantidade) AS quantidade 
		FROM esmovime e 
		WHERE e.cd_material = m.cd_material 
		AND e.cd_esp_estoque IN ('P', 'A', 'E')
		GROUP BY e.cd_material
	) e ON e.material = m.cd_material
	LEFT JOIN (
		SELECT s.cd_material as material, SUM(s.quantidade) AS quantidade 
		FROM esmovime s 
		WHERE s.cd_material = m.cd_material 
		AND s.cd_esp_estoque IN ('L', 'C', 'B')
		GROUP BY s.cd_material
	) s ON s.material = m.cd_material
WHERE
	m.dt_movimento = '2019-02-14'
V

mesmo erro, que estranho, se eu fizer apenas select cd_material from esmovime ai vem normal

L

Qual banco vc está usando?

V

sql server

L

Cara, esqueci o group by nos select internos. Atualizei a query, testa ai.

V

L

=/

Tenta tirar e.cd_material = m.cd_material dos 2 selects internos pra testar (deixa soh o IN).

SELECT
	m.cd_material AS material,
	e.quantidade AS "entradas",
	s.quantidade AS "saidas"
FROM
	esmovime m
	LEFT JOIN (
		SELECT e.cd_material as material, SUM(e.quantidade) AS quantidade 
		FROM esmovime e 
		WHERE e.cd_esp_estoque IN ('P', 'A', 'E')
		GROUP BY e.cd_material
	) e ON e.material = m.cd_material
	LEFT JOIN (
		SELECT s.cd_material as material, SUM(s.quantidade) AS quantidade 
		FROM esmovime s 
		WHERE s.cd_esp_estoque IN ('L', 'C', 'B')
		GROUP BY s.cd_material
	) s ON s.material = m.cd_material
WHERE
	m.dt_movimento = '2019-02-14'
V

nada… É um detalhe mas nao to achando…

L

To achando que eh algo que o sql server não aceita msm viu =/

V
Solucao aceita

Deu certo!, era somente um ajuste naquele modelo que você havia me passado, cara muito obrigado, não conseguiria fazer se a sua ajuda, valeu!

SELECT distinct
    m.cd_material AS material,
    d.descricao AS descricao,
    c.grupo AS grupo,
    ISNULL(e.quantidade,0) AS "entrada",
    ISNULL(s.quantidade,0) AS "saida",
    ISNULL(c.saldo,0) AS "saldo"
    FROM
    esmovime m
    LEFT JOIN (
      SELECT e.cd_material as material, SUM(e.quantidade) AS quantidade
      FROM esmovime e
      WHERE e.cd_esp_estoque IN ('P', 'A', 'E') and e.Dt_movimento = '2019-02-14'
      GROUP BY e.cd_material
    ) e ON e.material = m.cd_material
    LEFT JOIN (
      SELECT s.cd_material as material, SUM(s.quantidade) AS quantidade
      FROM esmovime s
      WHERE s.cd_esp_estoque IN ('L', 'C', 'B') and s.Dt_movimento = '2019-02-14'
      GROUP BY s.cd_material
    ) s ON s.material = m.cd_material
    LEFT JOIN(
      select c.Cd_sub_grupo as grupo ,c.Cd_material as material, c.qt_un1 as saldo from cgvw_posicaoestoque c
    ) c ON c.material = m.cd_material
      LEFT JOIN(
      select d.Descricao as descricao ,d.Cd_material as material from esmateri d
    ) d ON d.material = m.cd_material
    WHERE
    c.grupo<>'ESC' and c.grupo<>'DIV' and m.Dt_movimento = '2019-02-14' order by c.grupo asc, d.descricao asc
L

Top!

Criado 15 de fevereiro de 2019
Ultima resposta 16 de fev. de 2019
Respostas 28
Participantes 3