簡體   English   中英

僅選擇所有鏈接記錄都滿足條件的那些記錄

[英]Select only those records where all linked records fulfill a condition

我在兩個表之間有一個經典的1:n關系,如下所示: 在此處輸入圖片說明

我只需要為所有訂單選擇“ 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM