2011-12-31 79 views
0

我試圖將某些客戶訂單數據彙總到一張表中進行分析。數據是客戶訂購的產品數量,然後嘗試確定訂單是小訂單,中訂單還是大訂單,然後通過OrderSize確定他們購買的總產品和訂單的成本。聚合數據的最佳方式 - 更新查詢或子查詢?

小順序 - 1 - 2產品
中等順序 - 3 - 4產品
大訂單 - > = 5個產品

這裏是數據:

CustomerID OrderID OrderSize OrderTotal 
1   800  1   $20 
2   801  1   $10 
3   802  4   $85 
1   803  1   $30 
2   804  8   $120 
3   805  1   $40 

下面是表我我試圖構建(更容易只是張貼圖像): Table Screenshot

我可以運行這樣的更新查詢來填充選項卡樂:

- 建表 -

CREATE TABLE Customers (
    CustomerID varchar(10) PRIMARY KEY, 
    SmallOrderCount int, 
    SmallOrderProducts int, 
    SmallOrderTotal money, 
    MedOrderCount int, 
    MedOrderProducts int, 
    MedOrderTotal money, 
    LargeOrderCount int, 
    LargeOrderProducts int, 
    LargeOrderTotal money 
); 

- 將獨特的客戶 -

INSERT INTO Customers 
SELECT CustomerID FROM Orders GROUP BY CustomerID; 

- 更新填充訂單信息 -

UPDATE Customers 
SET SmallOrderCount = (SELECT count(*) FROM Orders WHERE OrderSize BETWEEN 1 AND 2 AND Orders.CustomerID = Customers.CustomerID); 

UPDATE Customers 
SET SmallOrderProducts = (SELECT sum(OrderSize) FROM Orders WHERE OrderSize BETWEEN 1 AND 2 AND Orders.CustomerID = Customers.CustomerID); 

UPDATE Customers 
SET SmallOrderTotal = (SELECT sum(OrderTotal) FROM Orders WHERE OrderSize BETWEEN 1 AND 2 AND Orders.CustomerID = Customers.CustomerID); 

然後我可以對剩下的6列重複這一點。

但是,這似乎很多工作。有沒有辦法使用子查詢來填充我的Customer表,這可能不太方便?或者我的方法是最直接的?

+0

另一方面:爲什麼要定義'CustomerID varchar(10)'?數據看起來像'integer'應該會做得更好? – 2011-12-31 19:03:17

回答

1

你可以做的這一切一個INSERT命令CASE語句:

INSERT INTO Customers 
SELECT CustomerID 
     ,sum(CASE WHEN OrderSize BETWEEN 1 AND 2 THEN 1 ELSE 0 END) AS SmallOrderCount 
     ,sum(CASE WHEN OrderSize BETWEEN 1 AND 2 THEN OrderSize ELSE 0 END) AS SmallOrderProducts 
     ,sum(CASE WHEN OrderSize BETWEEN 1 AND 2 THEN OrderTotal ELSE 0 END) AS SmallOrderTotal 
     ,sum(CASE WHEN OrderSize BETWEEN 3 AND 4 THEN 1 ELSE 0 END) AS MedOrderCount 
     ,sum(CASE WHEN OrderSize BETWEEN 3 AND 4 THEN OrderSize ELSE 0 END) AS MedOrderProducts 
     ,sum(CASE WHEN OrderSize BETWEEN 3 AND 4 THEN OrderTotal ELSE 0 END) AS MedOrderTotal 
     ,sum(CASE WHEN OrderSize > 4 THEN 1 ELSE 0 END) AS LargeOrderCount 
     ,sum(CASE WHEN OrderSize > 4 THEN OrderSize ELSE 0 END) AS LargeOrderProducts 
     ,sum(CASE WHEN OrderSize > 4 THEN OrderTotal ELSE 0 END) AS LargeOrderTotal 
FROM Orders 
GROUP BY CustomerID; 

看到這個working demo for the full query on data.SE

+0

感謝您的鏈接。我不知道data.se.com存在! – mikebmassey 2011-12-31 18:56:08

+0

@mikebmassey:這對演示SQL Server查詢非常方便。但最初的目的是讓用戶查詢SE數據庫。數據每月都會同步。 – 2011-12-31 18:59:00

0

您可以通過使用單個INSERT INTO SELECT語句來做到這

INSERT INTO Customers 
SELECT * , 
(SELECT count(*) FROM Orders WHERE OrderSize BETWEEN 1 AND 2 AND Orders.CustomerID = CustomerID), 
(SELECT sum(OrderSize) FROM Orders WHERE OrderSize BETWEEN 1 AND 2 AND Orders.CustomerID = CustomerID) 

FROM CUSTOMERS 
1

一個insert應該足夠:

INSERT INTO Customers(CustomerID,SmallOrderCount,SmallOrderProducts, 
    SmallOrderTotal)  
SELECT a.CustomerID, COUNT(a.*) as cnt, sum(a.OrderSize) as OrderSize, 
    sum(a.OrderTotal) as OrderTotal 
    FROM Orders a 
    WHERE a.OrderSize BETWEEN 1 AND 2 
    GROUP BY a.CustomerID 

上面的查詢將只插入客戶,其訂單規模爲1和2之間。如果您還需要插入其他人,您可以使用:

INSERT INTO Customers(CustomerID,SmallOrderCount,SmallOrderProducts, 
    SmallOrderTotal)  
SELECT a.CustomerID, 
COUNT(CASE WHEN a.OrderSize BETWEEN 1 AND 2 THEN 1 END) as cnt, 
sum(CASE WHEN a.OrderSize BETWEEN 1 AND 2 THEN a.OrderSize ELSE 0 END) as OrderSize, 
sum(CASE WHEN a.OrderSize BETWEEN 1 AND 2 THEN a.OrderTotal ELSE 0 END) as OrderTotal 
FROM Orders a 
GROUP BY a.CustomerID 
+0

對於每個組,這仍然需要多個更新查詢,對嗎? a.OrderSize在1和2之間,a.OrderSize在3和4之間,a.OrderSize> = 5,只需運行那3次? – mikebmassey 2011-12-31 18:40:12

+0

這隻適用於前三列('Small *'),並且不能像宣傳的那樣在一個INSERT中完成整個工作。 – 2011-12-31 18:44:56

+0

@mikebmassey:一個查詢,'SELECT'中只有6個字段(3個用於中型,3個用於大型)。對不起,我錯過了你的問題中的故障,所以我只發佈了很小。大中都是相似的,只是'CASE'中的不同條件。 – a1ex07 2011-12-31 20:50:00

1

我只創建一個查詢(可以用作視圖),而不是一個全新的持久表。

WITH cteOrders AS (
    SELECT CustomerID, 
     CASE WHEN OrderSize BETWEEN 1 AND 2 THEN OrderSize END SmallOrderProducts, 
     CASE WHEN OrderSize BETWEEN 1 AND 2 THEN OrderTotal END SmallOrderTotal, 
     CASE WHEN OrderSize BETWEEN 3 AND 4 THEN OrderSize END MediumOrderProducts, 
     CASE WHEN OrderSize BETWEEN 3 AND 4 THEN OrderTotal END MediumOrderTotal, 
     CASE WHEN OrderSize > 4 THEN OrderSize END LargeOrderProducts, 
     CASE WHEN OrderSize > 4 THEN OrderTotal END LargeOrderTotal 
    FROM Orders 
) 
SELECT CustomerID, 
     COUNT(SmallOrderProducts) SmallOrderCount, 
     COALESCE(SUM(SmallOrderProducts), 0) SmallOrderProducts, 
     COALESCE(SUM(SmallOrderTotal), 0) SmallOrderTotal, 
     COUNT(MediumOrderProducts) MediumOrderCount, 
     COALESCE(SUM(MediumOrderProducts), 0) MediumOrderProducts, 
     COALESCE(SUM(MediumOrderTotal), 0) MediumOrderTotal, 
     COUNT(LargeOrderProducts) LargeOrderCount, 
     COALESCE(SUM(LargeOrderProducts), 0) LargeOrderProducts, 
     COALESCE(SUM(LargeOrderTotal), 0) LargeOrderTotal 
    FROM cteOrders 
    GROUP BY CustomerID