[英]Select only those records where all linked records fulfill a condition
我只需要為所有訂單選擇“ 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)結合在一起,僅給出所有相關訂單均滿足條件的那些客戶。
如果有人發現一種更優雅的方式,請告訴我。
有什么建議如何解決這個問題?
在這種情況下,您無需考慮查找所有相關記錄均滿足條件的記錄。
相反,可以考慮在不存在破壞條件的相關記錄的地方找到所有記錄。
編寫此查詢最直接的方法是使用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'
我認為如果您需要多個條件(例如,最大日期范圍),這會更干凈。
只需找到要從中排除的記錄,然后放入一個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
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.