Tenho duas tabelas que contêm o mesmo tipo de dados, uma com dados do dia atual e outra com dados do dia anterior:
Atual:
CREATE TABLE Current (
Col1 VARCHAR(50),
Col2 VARCHAR(10),
Col3 VARCHAR(2),
Col4 DATE,
Col5 INT,
Col6 NUMERIC(5,2)
);
INSERT INTO Current (Col1, Col2, Col3, Col4, Col5, Col6)
VALUES
('ItemA', CASE WHEN LEFT('Ho', 1) = UPPER(LEFT('Ho', 1)) THEN 'Sell' ELSE 'Buy' END, 'Ho', '2025-07-01', 12345, 10.50),
('ItemA', CASE WHEN LEFT('oH', 1) = UPPER(LEFT('oH', 1)) THEN 'Sell' ELSE 'Buy' END, 'oH', '2025-08-01', 23456, 20.75),
('ItemB', CASE WHEN LEFT('Br', 1) = UPPER(LEFT('Br', 1)) THEN 'Sell' ELSE 'Buy' END, 'Br', '2025-07-01', 34567, 30.80),
('ItemC', CASE WHEN LEFT('rB', 1) = UPPER(LEFT('rB', 1)) THEN 'Sell' ELSE 'Buy' END, 'rB', '2025-09-01', 45678, 40.25),
('ItemC', CASE WHEN LEFT('Ho', 1) = UPPER(LEFT('Ho', 1)) THEN 'Sell' ELSE 'Buy' END, 'Ho', '2025-08-01', 56789, 50.60),
('ItemD', CASE WHEN LEFT('Br', 1) = UPPER(LEFT('Br', 1)) THEN 'Sell' ELSE 'Buy' END, 'Br', '2025-09-01', 67890, 60.10),
('ItemE', CASE WHEN LEFT('rB', 1) = UPPER(LEFT('rB', 1)) THEN 'Sell' ELSE 'Buy' END, 'rB', '2025-07-01', 78901, 70.95),
('ItemE', CASE WHEN LEFT('Ho', 1) = UPPER(LEFT('Ho', 1)) THEN 'Sell' ELSE 'Buy' END, 'Ho', '2025-08-01', 89012, 15.35);
Anterior:
CREATE TABLE Previous (
Col1 VARCHAR(50),
Col2 VARCHAR(10),
Col3 VARCHAR(2),
Col4 DATE,
Col5 INT,
Col6 NUMERIC(5,2)
);
INSERT INTO Previous (Col1, Col2, Col3, Col4, Col5, Col6)
VALUES
('ItemA', CASE WHEN LEFT('Ho', 1) = UPPER(LEFT('Ho', 1)) THEN 'Sell' ELSE 'Buy' END, 'Ho', '2025-07-01', 12350, 10.55),
('ItemA', CASE WHEN LEFT('oH', 1) = UPPER(LEFT('oH', 1)) THEN 'Sell' ELSE 'Buy' END, 'oH', '2025-08-01', 23461, 20.80),
('ItemB', CASE WHEN LEFT('Br', 1) = UPPER(LEFT('Br', 1)) THEN 'Sell' ELSE 'Buy' END, 'Br', '2025-07-01', 34572, 30.85),
('ItemC', CASE WHEN LEFT('rB', 1) = UPPER(LEFT('rB', 1)) THEN 'Sell' ELSE 'Buy' END, 'rB', '2025-09-01', 45683, 40.30),
('ItemC', CASE WHEN LEFT('Ho', 1) = UPPER(LEFT('Ho', 1)) THEN 'Sell' ELSE 'Buy' END, 'Ho', '2025-08-01', 56794, 50.65),
('ItemD', CASE WHEN LEFT('Br', 1) = UPPER(LEFT('Br', 1)) THEN 'Sell' ELSE 'Buy' END, 'Br', '2025-09-01', 67905, 60.15),
('ItemE', CASE WHEN LEFT('rB', 1) = UPPER(LEFT('rB', 1)) THEN 'Sell' ELSE 'Buy' END, 'rB', '2025-07-01', 78916, 70.90),
('ItemE', CASE WHEN LEFT('Ho', 1) = UPPER(LEFT('Ho', 1)) THEN 'Sell' ELSE 'Buy' END, 'Ho', '2025-08-01', 89027, 15.40);
Eu executo esta consulta com as 2 tabelas:
SELECT Col1, SUM(Col5) AS 'sum', 'C' AS 'Flag'
FROM Current
GROUP BY Col1
UNION
SELECT Col1, SUM(Col5) AS 'sum', 'P' AS 'Flag'
FROM Previous
GROUP BY Col1
ORDER BY Col1;
que retorna:
Col1 Sum Flag
ItemA 35801 C
ItemA 35811 P
ItemB 34567 C
ItemB 34572 P
ItemC 102477 P
ItemC 102467 C
ItemD 67905 P
ItemD 67890 C
ItemE 167913 C
ItemE 167943 P
Adicionei a coluna flag para maior clareza, para que você possa saber de onde os valores estão vindo. Preciso editar esta consulta para retornar uma tabela como esta:
Col1 Current Sum Previous Sum Difference
ItemA 35811. 35801 10
ItemB 34572 34567 5
ItemC 102477 102467 10
ItemD 67905 67890 15
ItemE 167943 167913 30
mas não consigo descobrir como selecionar os valores corretos a serem agregados, pois as tabelas são idênticas.
Editar: Devo observar que as tabelas exibem dados do dia atual e dados do dia anterior, então é possível que qualquer uma das tabelas contenha valores sem correspondência. Por exemplo, uma linha de dados pode "expirar" e ser incluída apenas na tabela anterior e não na atual. Uma linha também pode ser "adicionada" e ser incluída apenas na atual e não na anterior. Nesses casos, um valor precisaria ser preenchido como 0
Ao selecioná-los, selecione-os na coluna de saída em que você os deseja, por exemplo, a
Current
consulta vai para aCurrent Sum
coluna e aPrevious
consulta vai para aPrevious Sum
coluna.Devoluções conforme solicitado:
Nota 1: Não delimite os nomes das colunas com,
''
pois não é um delimitador oficial e tem consequências inesperadas em algumas situações.Nota 2: Você
UNION ALL
não precisaUNION
porqueUNION
remove duplicatas que você definitivamente não quer. E ele roda mais devagar por causa disso.Ficção DB
Eu apenas executaria os agregados separadamente e então a junção externa completa: