2016-03-30 4 views
3

私はcustomersとtransactionsテーブルを結合するクエリを持っています。この結合クエリのエイリアスはjqです。注文タイムスタンプ(order_ts)で各顧客の購入(取引)のランキングを作成したいと考えています。だから私は今、私は、以降の第五購入が集約された単一の行の代わりのように第五、第六、第七、及びになりたいランクまたはインデックス> = Nのローの集計

SELECT customer_id, 
     order_id, 
     order_ts, 
     RANK() OVER (PARTITION BY customer_id ORDER BY order_ts ASC), 
     amount 
FROM jq GROUP BY customer_id 
     ORDER BY customer_id; 

に、でした。合計された行は、5thのorder_idorder_tsを保持します。 MS SQL ServerとPostgresでこれをどうやって行うのですか?私が正しくあなたを理解している場合、あなたはCASE EXPRESSIONでこれを達成することができます

+0

に取得するには外側のクエリを使用して、このような何かを試してみてください何だろう集計後に 'order_id'と' order_ts'の値になりますか? –

+2

いくつかのサンプルデータとexptected結果してください。 .. – Squirrel

+0

@FelixPamittan質問を更新しました。 – menorah84

答えて

3

SELECT customer_id,min(order_id),min(order_ts), CASE WHEN rnk < 5 then rnk else 5 end as rnk,sum(amount) 
FROM(
    SELECT customer_id, 
      order_id, 
      order_ts, 
      RANK() OVER (PARTITION BY customer_id ORDER BY order_ts ASC) as rnk, 
      amount 
    FROM jq) 
GROUP BY customer_id, 
     CASE WHEN rnk < 5 then rnk else 5 end 
ORDER BY customer_id 

この意志グループ各RNK> 5として、1グループとしてそう。私はmin order_idを選択しました。それを選択すると、5番目のフォームが選択されます。

+2

優れたソリューションと効率的です。 +1 –

+0

SELECT customer_id、min(order_id)、min(order_ts)、** rnk **、sum(amount)... GROUP BY ** customer_id **、問題はありますか、@ sagi、私の疑問は**ですrnk **はGROUP BYには含まれていません –

+0

ありがとう@FelixPamittan – sagi

3

これにより正しい結果が得られますが、sagiのanswerが効率的です。


あなたはRANK < 5のための結果、フィルター上のSELECTを使用することができます。その後RANK >= 5

WITH Cte AS(
    SELECT 
     customer_id, 
     order_id, 
     order_ts, 
     RANK() OVER (PARTITION BY customer_id ORDER BY order_ts ASC) AS rnk, 
     amount 
    FROM jq 
    GROUP BY customer_id 
) 
SELECT 
    customer_id, 
    order_id, 
    order_ts, 
    rnk, 
    amount 
FROM Cte 
WHERE rnk < 5 

UNION ALL 

SELECT 
    customer_id, 
    MIN(order_id), 
    MIN(order_ts), 
    MIN(rnk), 
    SUM(amount) 
FROM Cte 
WHERE rnk >= 5 
GROUP BY customer_id 
ORDER BY customer_id; 

ため集計値にUNION ALLを行う*これは、SQL Serverのです

+0

これはjqから一度だけ選択できます。 – sagi

+0

これは多くの可能な解決策の1つにすぎません。あなたよりも効率的ではありません。 –

1

結果

SELECT customer_id,(CASE WHEN ROW_NO <5 THEN ROW_NO ELSE 5 END) ROW_NO, SUM(amount) amount 
FROM (
    SELECT customer_id, 
      order_id, 
      order_ts, 
      RANK() OVER (PARTITION BY customer_id ORDER BY order_ts ASC) ROW_NO, 
     amount 
FROM jq 
) D 
GROUP BY customer_id,(CASE WHEN ROW_NO <5 THEN ROW_NO ELSE 5 END) 
+0

正しい方法はありますが、正しい出力を提供していません(IDと日付がありません) – sagi

+0

uは* min(order_id)、min(order_ts)*はSUM(Amount)GROUP BY顧客ID。? –

+0

分(order_ts)は確かに有効ですが、それほど多くはありませんが、より大きな日付を前提とすると、より大きなIDを意味します。 – sagi