2016-03-11 162 views
0

長時間用戶,第一次發佈海報。按子查詢結果分組--SQL Server

這是關於使用子查詢的結果來聚合計數的問題。我完全開放地改變我的方法,但要確保沒有什麼容易的,我先失蹤了。

說我有訂單的表有以下欄目:

Order_Id 
Order_Datetime 
Order_Type 
Order_Status 

和我創建了一個索引視圖來支持最常用的讀訪問:

CREATE VIEW vw_OrdersByDate WITH SCHEMABINDING AS 
SELECT CONVERT(varchar(10), Order_Datetime, 121) AS Order_Date, 
     Order_Type, 
     Order_Status, 
     COUNT_BIG(*) 
    FROM Orders 
GROUP BY CONVERT(varchar(10), Order_Datetime, 121), Order_Type, Order_Status; 

CREATE UNIQUE CLUSTERED INDEX vw_OrdersByDate_main_idx ON 
     (Order_Date, Order_Type, Order_Status); 

到目前爲止,好。閱讀報告時(使用(noexpand)),它會在大約50M訂單中快速執行盲法。但是,現在我們已經推出了一種改變行業的產品,每個執行官都需要逐步瞭解產品如何移動。

我們有OrderLines的一個子表有以下幾列:

OrderLine_Id 
Order_Id 
Product_Id 

這裏就是問題所在,我會「像」的列添加到我原來的觀點,這樣我可以通過訂單篩選包含超級產品和那些沒有的超級產品。例如:

CREATE VIEW vw_OrdersByDate WITH SCHEMABINDING AS 
SELECT CONVERT(varchar(10), Order_Datetime, 121) AS Order_Date, 
     Order_Type, 
     Order_Status, 
     CASE WHEN EXISTS (SELECT 1 FROM OrderLines OL 
          WHERE OL.Order_Id = O.Order_Id 
          AND Product_Id = 123) THEN 1 
      ELSE 0 
     END AS Super_Product_Exists, 
     COUNT_BIG(*) 
    FROM Orders O 
GROUP BY CONVERT(varchar(10), Order_Datetime, 121), Order_Type, 
      Order_Status, Super_Product_Exists; 

但我不能這樣做。我已經嘗試將整個CASE語句放在GROUP BY子句中,並且「不能使用聚合或子查詢...對於按列表...」。我無法使用LEFT JOIN/NULL,因爲您無法使用任何類型的外部聯接在視圖上創建索引。

我覺得我錯過了一些簡單的東西,但無法弄清楚(而且Google也沒有......至少在我的搜索技能中)。

任何幫助將非常讚賞,就像我以前說過,我願意完全不同的策略,雖然我沒有很多的緯度改變現有的交易數據結構的...

謝謝!

回答

0

你需要結合到一起,你在你的外部查詢,這意味着有列你的存在,你必須揭露那些列在你的存在:

SELECT CONVERT(varchar(10), Order_Datetime, 121) AS Order_Date, 
     Order_Type, 
     Order_Status, 
     CASE WHEN EXISTS (SELECT 1 FROM OrderLines OL 
         INNER JOIN Orders OLO     
          ON OL.Order_Id = OLO.Order_Id 
         WHERE OLO.OrderType=O.OrderType 
         AND OLO.Order_Status=O.Order_Status 
          AND OL.Product_Id = 123) THEN 1 
      ELSE 0 
     END AS Super_Product_Exists, 
     COUNT_BIG(*) 
    FROM Orders O 
GROUP BY CONVERT(varchar(10), Order_Datetime, 121), Order_Type, 
      Order_Status; 
+0

只是一個小注:似乎沒有被'OrderType'或'Order_Status'表中的''OrderLines(據我可以看到)。 – Ralph

+0

不,這些列位於訂單中,這就是我在EXISTS查詢中加入訂單的原因。 –

+0

感謝您的回答Tab。這是我沒有考慮過的事情,當我將其更改爲COUNT而不是EXISTS時,它完全符合我的要求(在時間範圍內按訂單類型和狀態計算包含SuperProducts的訂單數量)。我還必須加入Order_Date,才能在規定的時間內獲得正確的計數,這並不美觀(但必要)。這就是說,顯然你不能在一個視圖上用子選擇創建一個索引,所以我需要找出其他的東西。 – Ckratide

0

假設你想看到的所有產品,並突出superproducts ,我添加了一個基於product_id = 123的計算字段,名爲superproduct,其值爲yes或no。

SELECT CONVERT(varchar(10),Orders.Order_datetime, 121) AS Order_Date, 
Orders.order_type, 
Orders.order_status, 
OrderLines.Product_id, 
CASE WHEN OrderLines.product_id =123 
    THEN 'Yes' 
    ELSE'No' 
END AS SuperProduct, 
COUNT_BIG(*) AS CountBig 
FROM Orders 
INNER JOIN OrderLines ON Orders.Order_id = OrderLines.Order_id 
GROUP BY 
CONVERT(varchar(10), 
Orders.Order_datetime, 121), 
Orders.order_type, 
Orders.order_status, 
OrderLines.Product_id 

Results

+0

請詳細說明給出的答案。純代碼答案通常很難理解。 – PVitt

+0

感謝DDD的迴應,我應該明確指出,需要使用SuperProducts和不具備SuperProducts的訂單,並且每個訂單都可以用於多個產品。我相信這樣會把兩種產品的單一訂單計算在一起。 – Ckratide