2013-02-26 21 views
4

我在SQL Server 2008 R2中有一個客戶和訂單表。兩者都有客戶ID(稱爲id)的索引。我需要返回有關客戶表中所有客戶的詳細信息以及訂單表中的信息,例如第一個訂單的詳細信息。在SQL Server中加入子查詢的效率

我當前將訂單表的子查詢中的客戶表加入,子查詢返回了我需要的關於訂單的信息。例如:

SELECT c.id 
     ,c.country  
     ,First_orders.product 
     ,First_orders.order_id 
FROM customers c 

LEFT JOIN SELECT(id, 
        product 
      FROM (SELECT id 
          ,product 
          ,order_id 
          ,ROW_NUMBER() OVER (PARTITION BY id ORDER BY Order_Date asc) as order_No 
         FROM orders) orders 
      WHERE Order_no = 1) First_Orders 
ON c.id = First_orders.id 

我對SQL很陌生,想要了解我是否有效地做到這一點。最後,我在一個select查詢中將這樣的子查詢添加到customers表中,並且可能需要幾十分鐘才能運行。

那麼,我是否有效地做到這一點,或者可以改進?例如,我不確定我的訂單表中的id索引是否有用,也許我可以通過首先創建一個子查詢中的內容的臨時表並在其中創建一個唯一索引來加速查詢。臨時表,所以SQL Server知道id現在是一個獨特的列,然後加入我的客戶表到這個臨時表?我通常在客戶和訂單表中有一兩百萬行。

非常感謝提前!

+1

從可讀性的角度來看,大多數SQL開發人員會盡量避免這樣的嵌套子查詢,如果他們能。在需要像這樣鏈接派生表的情況下,首選是通過'WITH'命令前綴使用CTE。性能方面,它不應該有任何區別,但這只是一個約定和可讀性的問題。 – RBarryYoung 2013-02-26 17:24:02

回答

1

對於剛剛學習SQL的人來說,您的查詢看起來相當不錯。

客戶索引可能會或可能不會用於查詢 - 您需要查看執行計劃。對於row_number函數,orders(id, order_date)上的索引可以非常有效地使用。

一個評論是關於字段的命名。字段orders.id不應該是客戶ID。這應該是'orders.Customer_Id`。保持跨表的命名系統一致將在未來幫助你。

4

您可以移除子查詢,使其多一點效率的一個:

SELECT c.id 
     ,c.country  
     ,First_orders.product 
     ,First_orders.order_id 
FROM customers c 
    LEFT JOIN (SELECT id 
        ,product 
        ,order_id 
        ,ROW_NUMBER() OVER (PARTITION BY id ORDER BY Order_Date asc) as order_No 
       FROM orders) First_Orders 
    ON c.id = First_orders.id AND First_Orders.order_No = 1 

在你上面的查詢,你需要你的地方你的括號,因爲我不認爲它會工作要小心。此外,您在結果中返回產品,但不包括在嵌套子查詢中。

0

嘗試......它很容易理解

WITH cte 
AS (
    SELECT id 
     ,product 
     ,order_id 
     ,ROW_NUMBER() OVER (
      PARTITION BY id ORDER BY Order_Date ASC 
      ) AS order_No 
    FROM orders 
    ) 
SELECT c.id 
    ,c.country 
    ,c1.Product 
    ,c1.order_id 
FROM customers c 
INNER JOIN cte c1 ON c.id = c1.id 
WHERE c1.order_No = 1