2017-07-31 8 views
0

私は、過去31日間に注文した各顧客の注文数と、過去に行った合計数を取得しようとしています。SQLで基準数と合計数を取得する - サブクエリが必要ですか?

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 

をしかし、私の限らこれまでのところ、私は最初の要件のために完璧に動作以下は、している

count total name   customer ID 
-------------------------------------------- 
3  10  Sarah Smith 22 
2  8  John Jenkins 15 
1  5  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 

すべての私のクエリは、過去31日間のカウントにWHERE句からロジックを移動することでした。そして、この新しいクエリはテーブル全体に渡っているので、生のカウントは期待出力のtotalに対応します。

+0

を使用することができます!私がここで学ぶ必要があるのは、「ケース」です。おかげさまでティム。 –

+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

あなたの 'having'節の' filter'は、私の答えが+1を上回ることに興味があります+1 –

+0

'FILTER'は役に立つツールのように思えます。 –

関連する問題