按滚动日期顺序对 MySQL 视图进行分组
Grouping MySQL view in a sequence of rolling dates
我有两个 tables:
Table Transmission
------------------------------
Id GroupID Amount Timestamp
1 1 5 2015-05-20 00:00:00
2 1 4 2015-05-19 00:00:00
3 1 10 2015-04-20 00:00:00
4 1 7 2015-04-19 00:00:00
5 1 9 2015-03-20 00:00:00
6 1 2 2015-03-18 00:00:00
Table Group
---------
Id DateCreated BillStart BillStop
1 2015-03-15 2015-05-15 2015-06-14
BillStart 和 BillStop 都有一个每天运行的触发器,如果当前日期大于 BillStop,两者 BillStart/BillStop 都会增加一个月(所以这些实际上是我们正在查看的当前范围)。
我已经有一个 SQL 视图可以汇总时间戳在 BillStart 和 BillStop 之间的一系列传输条目,我想要做的是有另一个视图可以有效地保存总和过去几个月的传输。即,如果 BillStart/BillStop 从 2015-05-15 到 2015-06-14,那么视图将知道将过去的传输从 2015-4-15 到 20-15-14、2015-3 的范围分组-15 到 2015-4-14,依此类推,直到包含组创建日期的最后一个范围。
理想情况下视图应该是这样的
-------------------------------------
GroupId Sum BillStart BillStop
1 9 2015-05-15 2015-06-14
1 17 2015-04-15 2015-05-14
1 11 2015-03-15 2015-04-14
有更好的方法吗?
我正在考虑的另一个选项是 table GroupBillRanges,它需要:
GroupBillRange
--------------
Id GroupId BillStart BillStop
1 1 2015-03-15 2015-04-14
2 1 2015-04-15 2015-05-14
3 1 2015-05-15 2015-06-14
这将在每个帐单范围按月更新时添加。这样我就可以将所有 Transmission.GroupId
匹配到 GroupDateRange.GroupId
是的,您需要创建 "GroupBillRange" table。否则,您会丢失旧组上的 Bill Start/Stop 日期的任何记录。 (当然,您可以假设它们总是从 15 号到 14 号。但一旦它们不是,您就会遇到问题。)一旦您这样做了,像下面这样的查询应该会为您提供您正在寻找的内容因为,我相信。 (哦,你把这个问题标记为 SQL Server 和 MySQL。所以我在 SQL Server 2008 r2 上创建了这个脚本。)
SET NOCOUNT ON;
DECLARE @Transmission TABLE (
ID int,
GroupID int,
Amount int,
TransmissionDate SmallDateTime );
INSERT @Transmission VALUES (1, 1, 5,'2015/05/20');
INSERT @Transmission VALUES (2, 1, 4,'2015/05/19');
INSERT @Transmission VALUES (3, 1,10,'2015/04/20');
INSERT @Transmission VALUES (4, 1, 7,'2015/04/19');
INSERT @Transmission VALUES (5, 1, 9,'2015/03/20');
INSERT @Transmission VALUES (6, 1, 2,'2015/03/18');
DECLARE @TableGroupRange TABLE (
ID int,
GroupID int,
BillStart SmallDateTime,
BillStop SmallDateTime );
INSERT @TableGroupRange VALUES (1, 1, '2015/03/15', '2015/04/14' )
INSERT @TableGroupRange VALUES (2, 1, '2015/04/15', '2015/05/14' )
INSERT @TableGroupRange VALUES (3, 1, '2015/05/15', '2015/06/14' )
SET NOCOUNT OFF;
SELECT TG.GroupID, SUM(T.Amount) as SumAmount, TG.BillStart, TG.BillStop
FROM @TableGroupRange TG
LEFT JOIN @Transmission T ON T.GroupID = TG.GroupID AND T.TransmissionDate BETWEEN TG.BillStart AND TG.BillStop
GROUP BY TG.GroupID, TG.BillStart, TG.BillStop
ORDER BY TG.GroupID, TG.BillStart, TG.BillStop
我有两个 tables:
Table Transmission
------------------------------
Id GroupID Amount Timestamp
1 1 5 2015-05-20 00:00:00
2 1 4 2015-05-19 00:00:00
3 1 10 2015-04-20 00:00:00
4 1 7 2015-04-19 00:00:00
5 1 9 2015-03-20 00:00:00
6 1 2 2015-03-18 00:00:00
Table Group
---------
Id DateCreated BillStart BillStop
1 2015-03-15 2015-05-15 2015-06-14
BillStart 和 BillStop 都有一个每天运行的触发器,如果当前日期大于 BillStop,两者 BillStart/BillStop 都会增加一个月(所以这些实际上是我们正在查看的当前范围)。
我已经有一个 SQL 视图可以汇总时间戳在 BillStart 和 BillStop 之间的一系列传输条目,我想要做的是有另一个视图可以有效地保存总和过去几个月的传输。即,如果 BillStart/BillStop 从 2015-05-15 到 2015-06-14,那么视图将知道将过去的传输从 2015-4-15 到 20-15-14、2015-3 的范围分组-15 到 2015-4-14,依此类推,直到包含组创建日期的最后一个范围。
理想情况下视图应该是这样的
-------------------------------------
GroupId Sum BillStart BillStop
1 9 2015-05-15 2015-06-14
1 17 2015-04-15 2015-05-14
1 11 2015-03-15 2015-04-14
有更好的方法吗?
我正在考虑的另一个选项是 table GroupBillRanges,它需要:
GroupBillRange
--------------
Id GroupId BillStart BillStop
1 1 2015-03-15 2015-04-14
2 1 2015-04-15 2015-05-14
3 1 2015-05-15 2015-06-14
这将在每个帐单范围按月更新时添加。这样我就可以将所有 Transmission.GroupId
匹配到 GroupDateRange.GroupId
是的,您需要创建 "GroupBillRange" table。否则,您会丢失旧组上的 Bill Start/Stop 日期的任何记录。 (当然,您可以假设它们总是从 15 号到 14 号。但一旦它们不是,您就会遇到问题。)一旦您这样做了,像下面这样的查询应该会为您提供您正在寻找的内容因为,我相信。 (哦,你把这个问题标记为 SQL Server 和 MySQL。所以我在 SQL Server 2008 r2 上创建了这个脚本。)
SET NOCOUNT ON;
DECLARE @Transmission TABLE (
ID int,
GroupID int,
Amount int,
TransmissionDate SmallDateTime );
INSERT @Transmission VALUES (1, 1, 5,'2015/05/20');
INSERT @Transmission VALUES (2, 1, 4,'2015/05/19');
INSERT @Transmission VALUES (3, 1,10,'2015/04/20');
INSERT @Transmission VALUES (4, 1, 7,'2015/04/19');
INSERT @Transmission VALUES (5, 1, 9,'2015/03/20');
INSERT @Transmission VALUES (6, 1, 2,'2015/03/18');
DECLARE @TableGroupRange TABLE (
ID int,
GroupID int,
BillStart SmallDateTime,
BillStop SmallDateTime );
INSERT @TableGroupRange VALUES (1, 1, '2015/03/15', '2015/04/14' )
INSERT @TableGroupRange VALUES (2, 1, '2015/04/15', '2015/05/14' )
INSERT @TableGroupRange VALUES (3, 1, '2015/05/15', '2015/06/14' )
SET NOCOUNT OFF;
SELECT TG.GroupID, SUM(T.Amount) as SumAmount, TG.BillStart, TG.BillStop
FROM @TableGroupRange TG
LEFT JOIN @Transmission T ON T.GroupID = TG.GroupID AND T.TransmissionDate BETWEEN TG.BillStart AND TG.BillStop
GROUP BY TG.GroupID, TG.BillStart, TG.BillStop
ORDER BY TG.GroupID, TG.BillStart, TG.BillStop