【发布时间】:2023-03-23 20:00:01
【问题描述】:
我有一个查询,它从表 CustomerDetails 中选择客户,然后左连接到另一个表 (CustomerActivity) 以获取他们的最后登录时间,最后左连接到另一个表 (OpenOrderDetails) 以获得他们的最后一次登录时间未结订单(如适用)。我还有一个很大的 WHERE 子句过滤这些数据
一个客户在任何时候都只能在OpenOrderDetails 表中拥有一条记录。我的查询如下所示:
SELECT CD.*, H.LastCustomerLoginTime, OD.OrderFiledDate, OD.OrderCompletedDate
FROM CustomerDetails CD
LEFT JOIN CustomerActivity H ON H.CustomerID = CD.CustomerID
LEFT JOIN OpenOrderDetails OD ON CD.CustomerID = OD.CustomerID
WHERE CD.OrderStatus IN (1,2,3)
AND (CustomerType = 1 or (CustomerType = 3 and CustomerActive IN (1,2)))
AND (OD.OrderFiledDate IS NULL OR CD.TimeStamp >= OD.OrderFiledDate)
AND (OD.OrderCompletedDate IS NULL OR CD.TimeStamp <= OD.OrderCompletedDate)
我的问题是这个查询只返回在OpenOrderDetails 表中有记录的客户记录。如何返回每个客户,如果存在 OrderFiledDate/OrderCompletedDate,如果 OpenOrderDetails 表中不存在该客户的记录,则返回 NULL?
【问题讨论】:
-
来自哪些表:字段
customerType和CustomerActive?这是一个常见的操作顺序问题。您希望保留连接的表上的过滤器作为连接的一部分出现。如果它们出现在 where 子句中,则 LEFT 连接的行为类似于内部连接。从逻辑上讲,这些表是连接的。然后 where 子句会消除不符合条件的值;包括由左连接生成的 NULLS。对 OD 的 is null 检查是一种不太常见但可接受的方法来保留左连接中的值,这就是我询问 CustomerActive 和 CustomerType 的原因。 -
*这个问题可能比简单的 where 子句限制更多。我猜想
customerType或CustomerActive中的一个或两个不在customerDetails 中。并且它也需要被移动到连接中或进行 is null 检查。 -
什么是
DLECS.CustomerID左二联?不应该是OD.CustomerID吗?定义的查询中不存在别名/表 DLECS。 -
@xQbert,打错字了,应该是 CD。根据您的问题,我同意您的关注,但选择的答案讲述了一个不同的故事。这个问题对我来说看起来很可疑;)
-
耸耸肩继续前进:P
标签: sql sql-server tsql left-join