我想编写一个查询来获得两个列之和的差异,这两个列分布在按月分组的两个表中。
架构:
表A
mass numeric,
weight numeric
sampleDt date
表B
mass numeric,
weight numeric,
sampleDt date
表A的示例数据
100|200|2017-01-03
10 |20 |2017-01-05
200|400|2017-12-23
表B的样本数据
10 | 20 | 2017-01-20
10 | 20 | 2017-01-21
100 | 200 | 2017-12-12
2 | 4 | 2017-06-12
预期输出
Month,Year |AMassTotal |AWeightTotal |BMassTotal |BWeightTotal |AMassTotal-BMassTotal
Jan,17 | 110 | 220 | 20 | 40 | 90
Jun,17 | 0 | 0 | 2 | 4 | -2
Dec,17 | 200 | 400 |100 |200 | 100
答案 0 :(得分:1)
使用完整的外部联接和分组:
select to_char(sampledt, 'yyyy-mm') as month_year,
coalesce(sum(a.mass),0) as a_mass_total,
coalesce(sum(a.weight),0) as a_weight_total,
coalesce(sum(b.mass),0) as b_mass_total,
coalesce(sum(b.weight),0) as b_weight_total,
coalesce(sum(a.mass),0) - coalesce(sum(b.mass),0) as mass_total_diff
from table_a a
full join table_b b using (sampledt)
group by to_char(sampledt, 'yyyy-mm');
如果您希望将年份和月份放在不同的列中,则可以使用:
select extract(year from sampledt) as year,
extract(month from sampledt) as month,
coalesce(sum(a.mass),0) as a_mass_total,
coalesce(sum(a.weight),0) as a_weight_total,
coalesce(sum(b.mass),0) as b_mass_total,
coalesce(sum(b.weight),0) as b_weight_total,
coalesce(sum(a.mass),0) - coalesce(sum(b.mass),0) as mass_total_diff
from table_a a
full join table_b b using (sampledt)
group by extract(year from sampledt), extract(month from sampledt)
order by 1,2;
除to_char()
函数外,上面是ANSI标准SQL。
答案 1 :(得分:0)
试试这个:
这适用于 SQL Server
:
SELECT CONVERT(CHAR(3), sampleDt, 0)+','+CAST(DATEPART(YEAR,sampleDt) AS VARCHAR) [Month,Year]
,ISNULL(SUM(CASE WHEN D.Tab=1 THEN mass END),0) AMassTotal
,ISNULL(SUM(CASE WHEN D.Tab=1 THEN weight END),0) AWeightTotal
,ISNULL(SUM(CASE WHEN D.Tab=2 THEN mass END),0) BMassTotal
,ISNULL(SUM(CASE WHEN D.Tab=2 THEN weight END),0) BWeightTotal
,ISNULL(SUM(CASE WHEN D.Tab=1 THEN mass END)-SUM(CASE WHEN D.Tab=2 THEN mass END),0) [AMassTotal-BMassTotal]
FROM(
SELECT 1 AS Tab,* FROM TableA
UNION ALL
SELECT 2,* FROM TableB
)D
GROUP BY LEFT(DATEPART(MONTH,sampleDt),3)+DATEPART(YEAR,sampleDt)
select CONVERT(CHAR(3), GETDATE(), 0)
SQL小提琴演示:SQL Fiddle Demo
答案 2 :(得分:0)
对于MySQL
SELECT TB.`Month,Year`,
IFNULL(AMassTotal,0),
IFNULL(AWeightTotal,0),
IFNULL(BMassTotal,0),
IFNULL(BWeightTotal,0),
(IFNULL(AMassTotal,0)-IFNULL(BMassTotal,0)) AS 'AMassTotal-BMassTotal'
FROM
(
SELECT DATE_FORMAT(sampleDt,'%M,%Y') AS `Month,Year`,
SUM(CASE WHEN mass IS NULL THEN 0 ELSE mass END) AS AMassTotal,
SUM(CASE WHEN weight IS NULL THEN 0 ELSE weight END) AS AWeightTotal
From TableA
GROUP BY DATE_FORMAT(sampleDt,'%M,%Y')
) AS TA
RIGHT JOIN
(
SELECT DATE_FORMAT(sampleDt,'%M,%Y') AS `Month,Year`,
SUM(CASE WHEN mass IS NULL THEN 0 ELSE mass END) AS BMassTotal,
SUM(CASE WHEN weight IS NULL THEN 0 ELSE weight END) AS BWeightTotal
FROM TableB
GROUP BY DATE_FORMAT(sampleDt,'%M,%Y')
) AS TB
ON TA.`Month,Year`=TB.`Month,Year`
现场演示