表1:
Order_ID Order_Type_ID NAME Date
1 1 Order1 03-07-16
2 2 Order2 01-21-16
表2:
ID Order_ID Event_Date
1 1 03-21-16
2 2 03-21-16
表3:
ID Order_Type_ID Repeat_Number Repeat_Sequence
1 1 3 2W
2 2 2 2M
我需要通过连接上面三个表来编写查询。在表1中,我有订单列表及其类型和日期。表2主要存储订单发送时的事件。表3有一个订单类型的交叉引用,它表示需要发送订单的次数以及在什么时间间隔内。示例:具有type_Id 1的订单需要每两周从订单开始发送三次。同样,具有type_Id 2的订单需要每两个月开始两次订单发送。
因此,基于事件表(表2),我需要编写查询来计算订单仍需要发送的次数以及下次发送的日期。
例如,我需要编写的查询应该显示如下内容:
Order_ID Sequence NAME Date
1 2 Order1 04-04-16
1 3 Order1 04-18-16
2 2 Order2 07-21-16
我可以使用子查询编写它,但想知道是否还有其他智能和快速的方法。
感谢您的帮助。
答案 0 :(得分:0)
您需要使用递归CTE。假设它是SQL Server,查询将如下所示:
;with c as(
SELECT t1.Order_ID, t1.Order_Type_ID, t1.NAME, t1.Date,
1 As Sequence, t3.Repeat_Number, t3.Repeat_Sequence
FROM #Table1 t1 INNER JOIN #Table3 t3 ON t1.Order_Type_ID = t3.Order_Type_ID
UNION ALL
SELECT c.Order_ID, c.Order_Type_ID, c.NAME, c.Date,
c.Sequence+1 As Sequence, c.Repeat_Number, c.Repeat_Sequence
FROM c WHERE c.Sequence < c.Repeat_Number)
select Order_ID, Order_Type_ID, Name, Sequence
, CASE WHEN Repeat_Sequence LIKE '%W' THEN DATEADD(week, Sequence * CAST(REPLACE(Repeat_Sequence, 'W', '') AS INT), Date)
WHEN Repeat_Sequence LIKE '%M' THEN DATEADD(month, Sequence * CAST(REPLACE(Repeat_Sequence, 'M', '') AS INT), Date) END from c
order by Order_ID, Sequence
结果:
Order_ID Order_Type_ID Name Sequence
----------- ------------- ------ ----------- -----------------------
1 1 Order1 1 2016-03-21 00:00:00.000
1 1 Order1 2 2016-04-04 00:00:00.000
1 1 Order1 3 2016-04-18 00:00:00.000
2 2 Order2 1 2016-03-21 00:00:00.000
2 2 Order2 2 2016-05-21 00:00:00.000
(5 row(s) affected)
如果您只想查看未来的订单,请过滤掉今天日期之前的任何记录。
请注意,此查询适用于Oracle或postgres,并对DATEADD函数进行了少量修改(在Postgres中,您将使用INTERVAL,在Oracle中,您可以在一周内添加7天,或者使用ADD_MONTHS数月)
<强>更新强>
如果您需要根据活动日期计算订单日期,可以将其加入查询,如下所示:
;with c as(
SELECT t1.Order_ID, t1.Order_Type_ID, t1.NAME, t2.Event_Date,
1 As Sequence, t3.Repeat_Number, t3.Repeat_Sequence
FROM #Table1 t1 INNER JOIN #Table3 t3 ON t1.Order_Type_ID = t3.Order_Type_ID
INNER JOIN #Table2 t2 ON t1.Order_ID = t2.Order_ID
UNION ALL
SELECT c.Order_ID, c.Order_Type_ID, c.NAME, c.Event_Date,
c.Sequence+1 As Sequence, c.Repeat_Number, c.Repeat_Sequence
FROM c WHERE c.Sequence < c.Repeat_Number)
select Order_ID, Order_Type_ID, Name, Sequence
, CASE WHEN Repeat_Sequence LIKE '%W' THEN DATEADD(week, Sequence * CAST(REPLACE(Repeat_Sequence, 'W', '') AS INT), Event_Date)
WHEN Repeat_Sequence LIKE '%M' THEN DATEADD(month, Sequence * CAST(REPLACE(Repeat_Sequence, 'M', '') AS INT), Event_Date) END from c
order by Order_ID, Sequence