2017-07-31 27 views
0

我試圖獲得在過去31天內訂購的每位客戶所做的訂單數量以及他們製作的總數量。我期望的輸出將如下所示:在SQL中獲取標準限制和總數 - 是否需要子查詢?

count total name   customer ID 
-------------------------------------------- 
3  10  Sarah Smith 22 
2  8  John Jenkins 15 
1  5  Delia Denton 44 

到目前爲止,我有以下的,這完全適用於第一個要求:

SELECT COUNT(o.id), CONCAT(c.first_name, ' ', c.last_name) AS name, c.id AS "customer ID" 
FROM orders o 
JOIN customers c ON c.id = o.customer_id 
WHERE order_date > (CURRENT_DATE - 31) 
GROUP BY name, "customer ID" 
ORDER BY count DESC 

主要生產:

count name   customer ID 
----------------------------------- 
3  Sarah Smith 22 
2  John Jenkins 15 
1  Delia Denton 44 

但是,我有限子查詢知識不會擴展到我可以如何集成一個來檢索此結果集中每個客戶的訂單總數。 (本質上是相同的查詢,但沒有日期限制。)我不確定是否(或如何)將此作爲過濾器以某種方式在所有訂單的總套數中使用,或者是否正確的方式是將返回的ID在這裏並將它們插入另一個查詢中。我該怎麼辦?我在PostgreSQL 9.4上。

回答

2

對整個表進行一次遍歷,並使用條件彙總計算最近31天的計數。

SELECT 
    COUNT(CASE WHEN order_date > (CURRENT_DATE - 31) THEN o.id END) AS cnt_31, 
    COUNT(o.id) AS total,  -- now this will count the grand total 
    CONCAT(c.first_name, ' ', c.last_name) AS name, 
    c.id AS "customer ID" 
FROM orders o 
INNER JOIN customers c 
    ON c.id = o.customer_id 
GROUP BY name, "customer ID" 
HAVING COUNT(CASE WHEN order_date > (CURRENT_DATE - 31) THEN o.id END) > 0 
ORDER BY count DESC 

我所有的查詢確實是邏輯從WHERE條款移入計數的最後31天。並且由於這個新的查詢遍佈整個表格,原始計數現在對應於您期望的輸出中的total

+0

這是完美的!我需要了解的是'CASE'。非常感謝蒂姆。 –

+2

另一種方式是'sum((order_date>(CURRENT_DATE - 31)):: integer)作爲cnt_31' – Jasen

+0

@Scott我給了你一個更新來過濾零31天計數。 –

2

正如另一種方式,在這樣的情況下,Postgres的版本> = 9.4, 可以使用filter條款

SELECT 
COUNT(o.id) as total_cnt, 
count(o.id) filter(WHERE order_date > (CURRENT_DATE - 31)) as last31_cnt, 
CONCAT(c.first_name, ' ', c.last_name) AS name, 
c.id AS "customer ID" 
FROM orders o 
JOIN customers c ON c.id = o.customer_id 
GROUP BY name, "customer ID" 
having count(o.id) filter(WHERE order_date > (CURRENT_DATE - 31)) > 0 
ORDER BY total_cnt DESC 
+0

這將是有趣的,它''過濾器''條款將超過我的答案+1 –

+0

'FILTER'似乎是一個有用的工具 - 感謝Oto。 –