2013-05-21 38 views
1

這很簡單。MySQL:選擇已完成行的訂單

我有兩個表:ORDERS和ORDER_LINES。很簡單,不言自明;這是一種一對多的關係。 ORDER_LINES有一個FULFILLED列,其中包含該特定行完成時的日期。

以下是我需要做的事情:選擇已完成訂單的所有ORDERS.ID;即對於該特定順序,ORDER_LINES表中沒有任何FULFILLED列爲NULL。

實施例:

訂單#1有兩條線,這兩者都是不爲空

訂單#2具有一個線是空

查詢應只返回#1,因爲它是完成。

回答

0
Select * 
From orders As O 
Where Not Exists (
        Select 1 
        From order_lines As OL1 
        Where OL1.Fullfilled Is Null 
         And OL1.OrderId = O.OrderId 
        ) 

SQL Fiddle version

它使用在功能的替代版本:

Select * 
From orders As O 
Where O.OrderId Not In (
          Select OL1.OrderId 
          From order_lines As OL1 
          Where OL1.Fullfilled Is Null 
         ) 

SQL Fiddle version

加成

有一個願望使用聚合函數完成此操作。雖然下面是一個解決方案,即使用Exists和在功能形式表達的意圖比下面的查詢要好得多,所以我建議那些兩種形式之一了:

Select O.OrderId 
From Orders As O 
    Left Join Order_Lines As OL 
     On OL.OrderId = O.OrderId 
      And OL.Fullfilled Is Null 
Group By O.OrderId 
Having Count(OL.Id) = 0 

SQL Fiddle version

然而,

Select O.OrderId 
From Orders As O 
    Left Join Order_Lines As OL 
     On OL.OrderId = O.OrderId 
      And OL.Fullfilled Is Null 
Where OL.Id Is Null 

SQL Fiddle version

+0

是否有一個'清潔',聚合函數,將做到這一點,而不是嵌套的SELECT? – JFriend

+0

@JFriend - 從技術上講,是的,有一種方法可以用一個聚合函數來完成它,但爲什麼你想這樣做呢?它不會像Exists或In函數那樣表達您的意圖。 – Thomas

+0

我只想着一個非常大的數據庫(16M訂單行,30個併發用戶)的開銷和資源。 – JFriend

0

使用左加入,加入的條件:它可能會表現最佳的另一種形式僅查詢所需列中不爲空的行。喜歡這個。

SELECT ORDERS.ID 
FROM ORDERS 
LEFT JOIN ORDER_LINES 
    ON (ORDERS.ID = ORDER_LINES.ORDER_ID) 
WHERE ORDER_LINES.ORDER_ID is not null 
+0

這不行......你必須檢查履行的專欄,看看是否所有行[每個訂單]都完成了。 – JFriend