如何在 SQL 中按年份汇总数据?
How can I summarize data by year in SQL?
我确信这个请求相当直截了当,但我被卡住了。我想把下面的第一个 table 和 Year
相加 Incremental_Inventory
变成第二个 table。
+-------------+-----------+----------------------+-----+
|Warehouse_ID |Date |Incremental_Inventory |Year |
+-------------+-----------+----------------------+-----+
| 1|03/01/2010 |125 |2010 |
| 1|08/01/2010 |025 |2010 |
| 1|02/01/2011 |150 |2011 |
| 1|03/01/2011 |200 |2011 |
| 2|03/01/2012 |125 |2012 |
| 2|03/01/2012 |025 |2012 |
+-------------+-----------+----------------------+-----+
至
+-------------+-----------+---------------------------+
|Warehouse_ID |Date |Cumulative_Yearly_Inventory|
+-------------+-----------+---------------------------+
| 1|03/01/2010 |125 |
| 1|08/01/2010 |150 |
| 1|02/01/2011 |150 |
| 1|03/01/2011 |350 |
| 2|03/01/2012 |125 |
| 2|03/01/2012 |150 |
+-------------+-----------+---------------------------+
如果您的 DBMS(您没有告诉我们)支持 window 功能,您可以简单地执行以下操作:
SELECT warehouse_id,
date,
sum(incremental_inventory) OVER (PARTITION BY warehouse_id,
year(date)
ORDER BY date) cumulative_yearly_inventory
FROM elbat
ORDER BY date;
year()
可能需要替换为您的 DBMS 提供的从日期中提取年份的方法。
如果它不支持 window 函数,您必须使用子查询和聚合。
SELECT t1.warehouse_id,
t1.date,
(SELECT sum(t2.incremental_inventory)
FROM elbat t2
WHERE t2.warehouse_id = t1.warehouse_id
AND year(t2.date) = year(t1.date)
AND t2.date <= t1.date) cumulative_yearly_inventory
FROM elbat t1
ORDER BY t1.date;
但是,如果有两个相同的日期,这将为它们打印相同的总和。人们需要另一个不同的列来解决这个问题,据我所知,你在 table.
中没有这样的列
我不确定您是想要所有仓库的总和还是仅每个仓库的总和。如果您不想按仓库拆分总和,而是希望所有仓库总计一个总和,请从 PARTITION BY
或内部 WHERE
子句中删除相应的表达式。
如果您有 SAS/ETS,那么时间序列任务将为您执行此操作。假设不是,这是一个数据步骤解决方案。
- 使用 RETAIN 跨行保存值
使用BY来标识每年的第一条记录
data want;
set have;
by year;
retain cum_total;
if first.year then cum_total=incremental_inventory;
else cum_total+incremental_inventory;
run;
我确信这个请求相当直截了当,但我被卡住了。我想把下面的第一个 table 和 Year
相加 Incremental_Inventory
变成第二个 table。
+-------------+-----------+----------------------+-----+
|Warehouse_ID |Date |Incremental_Inventory |Year |
+-------------+-----------+----------------------+-----+
| 1|03/01/2010 |125 |2010 |
| 1|08/01/2010 |025 |2010 |
| 1|02/01/2011 |150 |2011 |
| 1|03/01/2011 |200 |2011 |
| 2|03/01/2012 |125 |2012 |
| 2|03/01/2012 |025 |2012 |
+-------------+-----------+----------------------+-----+
至
+-------------+-----------+---------------------------+
|Warehouse_ID |Date |Cumulative_Yearly_Inventory|
+-------------+-----------+---------------------------+
| 1|03/01/2010 |125 |
| 1|08/01/2010 |150 |
| 1|02/01/2011 |150 |
| 1|03/01/2011 |350 |
| 2|03/01/2012 |125 |
| 2|03/01/2012 |150 |
+-------------+-----------+---------------------------+
如果您的 DBMS(您没有告诉我们)支持 window 功能,您可以简单地执行以下操作:
SELECT warehouse_id,
date,
sum(incremental_inventory) OVER (PARTITION BY warehouse_id,
year(date)
ORDER BY date) cumulative_yearly_inventory
FROM elbat
ORDER BY date;
year()
可能需要替换为您的 DBMS 提供的从日期中提取年份的方法。
如果它不支持 window 函数,您必须使用子查询和聚合。
SELECT t1.warehouse_id,
t1.date,
(SELECT sum(t2.incremental_inventory)
FROM elbat t2
WHERE t2.warehouse_id = t1.warehouse_id
AND year(t2.date) = year(t1.date)
AND t2.date <= t1.date) cumulative_yearly_inventory
FROM elbat t1
ORDER BY t1.date;
但是,如果有两个相同的日期,这将为它们打印相同的总和。人们需要另一个不同的列来解决这个问题,据我所知,你在 table.
中没有这样的列我不确定您是想要所有仓库的总和还是仅每个仓库的总和。如果您不想按仓库拆分总和,而是希望所有仓库总计一个总和,请从 PARTITION BY
或内部 WHERE
子句中删除相应的表达式。
如果您有 SAS/ETS,那么时间序列任务将为您执行此操作。假设不是,这是一个数据步骤解决方案。
- 使用 RETAIN 跨行保存值
使用BY来标识每年的第一条记录
data want; set have; by year; retain cum_total; if first.year then cum_total=incremental_inventory; else cum_total+incremental_inventory; run;