Sql 如何联接三个表并编写查询?
表1: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
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中的事件_日期开始计算。如果我不清楚,请告诉我。