使用左外连接的SQL Server递归查询

时间:2017-01-07 19:37:16

标签: sql-server-2008-r2 recursive-query

我有两个表格CustomersOrders以及一些数据。

SELECT * FROM  Customers C;

结果:

CustomerId  Name
--------------------    
1           Shree;
2           Kalpana;
3           Basavaraj;

查询:

select * from Orders O;

结果:

OrderId   CustomerId    OrderDate
-------------------------------------------------
100           1         2017-01-05 23:16:15.497
200           4         2017-01-06 23:16:15.497
300           3         2017-01-07 23:16:15.497

我有业务需求,我需要以重复的方式从客户左外连接订单填充数据。我写了下面的查询和所需的数据。

SELECT * 
FROM Customers C
LEFT OUTER JOIN 
    (SELECT * 
     FROM Orders 
     WHERE OrderId = 100) O ON O.CustomerId = C.CustomerId

UNION ALL

SELECT * 
FROM Customers C
LEFT OUTER JOIN 
    (SELECT * 
     FROM Orders 
     WHERE OrderId = 200) O ON O.CustomerId = C.CustomerId

UNION ALL

SELECT * 
FROM Customers C
LEFT OUTER JOIN 
    (SELECT * 
     FROM Orders 
     WHERE OrderId = 300) O ON O.CustomerId = C.CustomerId;

期望的结果:

CustomerId  Name       OrderId  CustomerId  OrderDate
--------------------------------------------------------------------
1           Shree      100      1           2017-01-05 23:16:15.497
2           Kalpana    NULL     NULL        NULL
3           Basavaraj  NULL     NULL        NULL
1           Shree      NULL     NULL        NULL
2           Kalpana    NULL     NULL        NULL
3           Basavaraj  NULL     NULL        NULL
1           Shree      NULL     NULL        NULL
2           Kalpana    NULL     NULL        NULL
3           Basavaraj  300      3           2017-01-07 23:16:15.497

我有一个选项可以将左外部查询放在循环中并传递OrderId,最后保存结果数据,但由于记录数量很多,这需要很多时间。我想知道完成这项工作的最佳方法。我尝试过功能和CTE但到目前为止还没有运气。请帮忙。

非常感谢提前。

2 个答案:

答案 0 :(得分:0)

笛卡儿产品可以完成这项工作:

SELECT  C.*, 
        OrderId = CASE WHEN C.CustomerId = O.CustomerID THEN O.OrderId ELSE NULL END,
        CustomerId = CASE WHEN C.CustomerId = O.CustomerID THEN O.CustomerId ELSE NULL END,
        OrderDate = CASE WHEN C.CustomerId = O.CustomerID THEN O.OrderDate ELSE NULL END
FROM Orders O, Customers C 

答案 1 :(得分:0)

我使用类似于笛卡尔积的解决方案。将CustomerId存储在表变量中,而不是使Cartesian生成相同。这是我想要的。

声明@CustomerTable TABLE(ID int IDENTITY(1,1)NOT NULL,CustomerId int); 插入@CustomerTable从订单中选择不同的CustomerId;

选择v.ID,isnull(v.CT_CustomerId,o.CustomerId)作为CT_CustomerId,v.CustomerId,v.Name,o。*来自 (选择CT.ID,CT.CustomerId为CT_CustomerId,C.CustomerId,C.Name来自@CustomerTable CT,客户C)V left outer join命令O ON O.CustomerId = V.CustomerId和V.ID = o.ID