2017-11-30 25 views
0

私は、以下の情報を含むテーブルを持っている:私は、パーティショニングで何かがあることを知っている塗りつぶしテーブル

ranked_id | id | amount | date | customer_id 
     1 | 1 | 0.00 | 11/12/17 | 1 
     2 | 2 | 54.00 | 11/12/17 | 1    
     3 | 3 | 60.00 | 02/12/18 | 1 
     4 | 3 | 60.00 | 02/12/18 | 1 
     5 | 3 | 60.00 | 02/12/18 | 1 
     6 | 3 | 60.00 | 02/12/18 | 1 
     7 | 3 | 60.00 | 02/12/18 | 1 
     8 | 4 | 0.00 | 01/18/17 | 2 
     9 | 5 | 14.00 | 03/12/17 | 2 
     10 | 6 | 24.00 | 02/22/18 | 2 
     11 | 6 | 24.00 | 02/22/18 | 2 
     12 | 6 | 24.00 | 02/22/18 | 2 
     13 | 6 | 24.00 | 02/22/18 | 2 
     14 | 6 | 24.00 | 02/22/18 | 2 
     15 | 7 | 0.00 | 09/12/16 | 3 
     16 | 8 | 74.00 | 10/01/17 | 3 
     17 | 8 | 74.00 | 10/01/17 | 3 
     18 | 8 | 74.00 | 10/01/17 | 3 
     19 | 8 | 74.00 | 10/01/17 | 3 
     20 | 8 | 74.00 | 10/01/17 | 3 
     21 | 8 | 74.00 | 10/01/17 | 3 

id | amount | date | customer_id 
1 | 0.00 | 11/12/17 | 1 
2 | 54.00 | 11/12/17 | 1 
3 | 60.00 | 02/12/18 | 1 
4 | 0.00 | 01/18/17 | 2 
5 | 14.00 | 03/12/17 | 2 
6 | 24.00 | 02/22/18 | 2 
7 | 0.00 | 09/12/16 | 3 
8 | 74.00 | 10/01/17 | 3 

私はそれが見えるように必要なもの次は(rank_id上で)ランキングしていますが、最後の行を7回繰り返す方法がわかりません。

+1

結果の背後にある論理を説明できますか? – Mureinik

+0

私はそれは私がそれをやって考えることができる唯一の方法だ をamount_7&date_7し、これらの結果を取り、アップ amount_1 DATE_1 amount_2 日付2 ... すべての道にそれらを配置する必要があります。 –

答えて

1

:次に、あなたが欲しいものを選ぶことができます。次にT2(以下も同様)で、row_number関数を使用して、t1からcustomer_idへの外部結合への連続値を生成します。

ケースステートメントと分析first_value関数が入っている元のデータがない場合、customer_idごとに最後の値を取得することができます。last_valueを取得できませんでしたpostgresqlに無視ヌル・ディレクティブがないために解析機能が動作する可能性があるため、first_Valueを降順ソート順で使用し、他のデータが存在しない場合にのみ解析値を戻します。

with t1 as (
select distinct 
     dense_rank() over (order by customer_id, generate_series) ranked_id 
    , customer_id 
    , generate_series 
    from table1 
    cross join generate_series(1,7) 
), t2 as (
    select row_number() over (partition by customer_id order by id) rn 
     , table1.* 
    from table1 
) 
select t1.ranked_id 
    , case when t2.customer_id is not null 
      then t2.id 
      else first_value(t2.id) 
       over (partition by t1.customer_id 
         order by id desc nulls last) 
     end id 
    , case when t2.customer_id is not null 
      then t2.amount 
      else first_value(t2.amount) 
       over (partition by t1.customer_id 
         order by id desc nulls last) 
     end amount 
    , case when t2.customer_id is not null 
      then t2.date 
      else first_value(t2.date) 
       over (partition by t1.customer_id 
         order by id desc nulls last) 
     end date 
    , t1.customer_id 
    from t1 
    left join t2 
    on t2.customer_id = t1.customer_id 
    and t2.id = t1.generate_series 
order by ranked_id; 

ここにコードを示すSQL Fiddleがあります。

+0

ええ、この事は獣ですが、それは私が持っている問題を解決します。私は「ORDER BY ranked_id」を「ORDER BY id、ranked_id」に変更して、必要な順番でそれを取得しなければなりませんでした。 センティネルとゴードン・リノフの両方に感謝します。 –

1

Postgresでは、generate_series()とクロスジョインを使用してすべての行を生成できます。 @Gordon Linoffはあなたが以下のT1のように必要なすべての行を生成する()関数は、明確なcustomer_idsと交配generate_seriesを使用することができます示唆したように

select row_number() over (order by customer_id, id) as ranking_id, 
     coalesce(t.id, cid) as id, coalesce(t.amount, c.amount) as amount 
     coalesce(t.date, c.date) as date, t.customer_id 
from (select distinct on (customer_id) t.* 
     from t 
     order by customer_id, date desc 
    ) c cross join 
    generate_series(1, 7) g(i) left join 
    (select t.*, row_number() over (partition by customer_id order by date) as i 
     from t 
    ) t 
    on t.customer_id = c.customer_id and t.i = g.i; 
関連する問題