Sql 如何联接三个表并编写查询?

Sql 如何联接三个表并编写查询?,sql,join,Sql,Join,表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

表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列出了订单类型的交叉引用,说明了订单需要发送多少次以及发送间隔。示例:从订单开始日期起,每两周需要发送三次类型为_Id 1的订单。类似地,从订单开始日期起,每两个月需要发送两次类型为_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
我可以使用子查询编写它,但我想知道是否还有其他智能和快速的方法


谢谢你的帮助

您需要为此使用递归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
;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
如果您只想查看未来的订单,请过滤掉任何小于今天日期的记录

请注意,此查询将适用于Oracle或postgres,只需对postgres中的DATEADD函数稍作修改即可。您将使用INTERVAL,在Oracle中,您可以每周添加7天,也可以使用add_MONTHS

更新:

如果需要根据事件日期计算订单日期,可以将其加入查询,如下所示:

;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
;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

您使用的是哪个数据库?在预期的输出中有一个列序列,它不在表1、表2或表3中。请用清晰的格式叙述这篇文章。顺序是一个递增的数字,应该代表开始发送的第n个时间顺序。例如,表2有一个订单ID为1的事件,这意味着订单发送了一次,需要再发送两次,即序列2和3。感谢您的回答,我工作得很好。但是,是否可以根据表2中的事件来决定和计算下一个订单数据?因为如果我改变表3中的Repeat_序列,输出就会改变。所以,根据表2中的事件,我需要计算订单需要发送的次数,下一个发送日期应该从表2中的事件_日期开始计算。如果我不清楚,请告诉我。