我只需要为所有订单选择那些'NOT OrderDate IS NULL'的客户。我从
开始SELECT Customers.Id, Customers.LastName
FROM Customers, Orders
WHERE Customers.Id = Orders.CustomerId AND NOT Orders.OrderDate IS NULL AND ...
并希望通过'FOR ALL'进一步构建,但失败了。
我尝试了答案中给出的建议但没有给出正确的结果。
以下是我的解决方法,其中包含两个临时表,如下所示:
DECLARE @TableA TABLE (
Id int,
CountA int
)
DECLARE @TableB TABLE (
Id int,
CountB int
)
INSERT INTO @TableA (Id, CountA)
SELECT Customers.Id, COUNT(Orders.Id)
FROM Customers INNER JOIN
Orders ON Customers.Id = Orders.CustomerId
GROUP BY Customers.ID
INSERT INTO @TableB (Id, CountB)
SELECT Customers.Id, COUNT(Orders.Id)
FROM Customers INNER JOIN
Orders ON Customers.Id = Orders.CustomerId
WHERE (NOT Orders.OrderDate IS NULL)
GROUP BY Customers.ID
Select tA.Id
FROM @TableA tA INNER JOIN @TableB tB on tA.Id = tB.Id
WHERE tA.CountA = tB.CountB
两个临时表的不同之处在于,第一个临时表在Orders中选择没有条件的组计数,第二个临时表用条件选择它们。然后加入两个临时表,其中CountA = CountB仅给出所有相关订单满足条件的客户。
如果有人找到更优雅的方式,请告诉我。
答案 0 :(得分:2)
有任何建议如何解决这个问题?
在这种情况下,您需要考虑的不是找到所有相关记录满足条件的记录。
相反,考虑找到所有记录,而不存在破坏条件的相关记录。
答案 1 :(得分:1)
编写此查询的最简单方法是使用ALL:
SELECT Customers.Id, Customers.LastName
FROM Customers
WHERE '2000-01-01' < ALL(SELECT OrderDate FROM Orders WHERE Orders.CustomerId = Customers.Id)
您也可以在订单表上将其写为群组查询,例如
WITH CustomerOrderDateRange(CustomerId, MinOrderDate, MaxOrderDate) AS (
SELECT CustomerId, MIN(OrderDate), MAX(OrderDate)
FROM Orders
GROUP BY CustomerId
)
SELECT Customers.Id, Customers.LastName
FROM Customers
JOIN CustomerOrderDateRange
ON Customers.Id = CustomerOrderDateRange.CustomerId
WHERE
CustomerOrderDateRange.MinOrderDate > '2000-01-01'
如果您需要多个条件,我认为这样更清晰,例如最大日期范围。
答案 2 :(得分:0)
只需找到要从中排除的记录,然后输入not in子句
select *
from Customers
where Customers.Id not in (
SELECT Customers.Id
FROM Customers
join Orders on Customers.Id = Orders.CustomerId
WHERE Orders.OrderDate < '2000-01-01'
group by Customers.Id
)