2017-12-19 7 views
0

列ごとの値を取得する必要があるSQLの問題がある(Redshift上)index ID final_scoreの最大値に基づいて列idを入力し、この値を新しい列fav_indexに入力します。 score2は= index n + 1index nは、例えば、= abc1id、= 0index及び= 10score1ためscore2の値がindex = 1score1の値となるとfinal_scoreの値との差であるscore1の値に等しいです。 score1およびscore2Redshift - グループ化ID列Bの各IDの1つの列Aの値を別の列の最大値に基づいて取得するC

テーブルscoreを見れば簡単です。このテーブルscoreは、後で示すSQLクエリの結果です。だから、

id index score1 score2 final_score 
abc1 0  10  20  10 
abc1 1  20  45  25 
abc1 2  45  (null) (null) 
abc2 0  5   10  5 
abc2 1  10  (null) (null) 
abc3 0  50  30  -20 
abc3 1  30  (null) (null) 

、列fav_indexを含む結果のテーブルには、次のようになります。storyとしてある

select 
    m.id, 
    m.index, 
    max(m.max) as score1, 
    fmt.score2, 
    round(fmt.score2 - max(m.max), 1) as final_score 
from 
    (select 
     sv.id, 
     case when sv.story_number % 2 = 0 then cast(sv.story_number/2 - 1 as int) else cast(floor(sv.story_number/2) as int) end as index, 
     max(sv.score1) 
    from 
     story as sv 
    group by 
     sv.id, 
     index, 
     sv.score1 
    order by 
     sv.id, 
     index 
    ) as m 
left join 
    (select 
     sv.id, 
     case when sv.story_number % 2 = 0 then cast(sv.story_number/2 - 1 as int) else cast(floor(sv.story_number/2) as int) end as index, 
     max(score1) as score2 
    from 
     story as sv 
    group by 
     id, 
     index 
    ) as fmt 
    on 
     m.id = fmt.id 
    and 
     m.index = fmt.index - 1 
group by 
    m.id, 
    m.index, 
    fmt.score2 

表:以下

id index score1 score2 final_score fav_index 
abc1 0  10  20  10    0 
abc1 1  20  45  25    1 
abc1 2  45  (null) (null)   0 
abc2 0  5   10  5    0 
abc2 1  10  (null) (null)   0 
abc3 0  50  30  -20   0 
abc3 1  30  (null) (null)   0 

は、テーブル storyからテーブル scoreを生成するためのスクリプトです以下:

id story_number score1 
abc1 1    10 
abc1 2    10 
abc1 3    20 
abc1 4    20 
abc1 5    45 
abc1 6    45 

私は考えることができる唯一の解決策は、何かなどを行う

select id, max(final_score) from score group by id 

、その後バック(表scoreを生成するために使用された)上記の長いスクリプトにそれに参加することです。私は本当に必要な情報を1列だけ追加するために、このような長いスクリプトを書くのを避けたいと思っています。

これを行うより良い方法はありますか?

ありがとうございました!

更新:mysqlの回答も受け付けます。ありがとう!

+0

「MySQL」または「SQL Server」? – Squirrel

+1

mysqlをタグとして削除してください/あなたのコメントを更新してください。mysqlはredshiftとは関係ありません。 –

+2

あなたは間違っています - mysqlは普遍的な用語ではなく、赤方偏移とはかなり異なっています。この質問に対するmysqlの回答は、赤方偏移の修正を加えてもほぼ確実に機能しません。 –

答えて

0

この上でより多くの時間を過ごし、周りの人に尋ねた後、私は最終的に、このウィンドウ関数のドキュメントを参照して解決策を考え出した - PostgreSQLのhttps://www.postgresql.org/docs/9.1/static/tutorial-window.html

私は基本的には上部に2×select文と1×where文を追加一番下にwhereステートメントは、final_score = nullの行を処理することです。そうしないと、rank()関数は1とランク付けされるためです。

私のコードは、その後、次のようになります。

select 
    id, index, final_score, rank, case when rank = 1 then index else null end as fav_index 
from 
(select 
    id, index, final_score, rank() over (partition by id order by final_score desc) 
from 
(select 
    m.id, 
    m.index, 
    max(m.max) as score1, 
    fmt.score2, 
    round(fmt.score2 - max(m.max), 1) as final_score 
from 
    (select 
     sv.id, 
     case when sv.story_number % 2 = 0 then cast(sv.story_number/2 - 1 as int) else cast(floor(sv.story_number/2) as int) end as index, 
     max(sv.score1) 
    from 
     story as sv 
    group by 
     sv.id, 
     index, 
     sv.score1 
    order by 
     sv.id, 
     index 
    ) as m 
left join 
    (select 
     sv.id, 
     case when sv.story_number % 2 = 0 then cast(sv.story_number/2 - 1 as int) else cast(floor(sv.story_number/2) as int) end as index, 
     max(score1) as score2 
    from 
     story as sv 
    group by 
     id, 
     index 
    ) as fmt 
    on 
     m.id = fmt.id 
    and 
     m.index = fmt.index - 1 
group by 
    m.id, 
    m.index, 
    fmt.score2) 
where 
    final_score is not null) 

そして、次のように結果は次のとおりです。

id index final_score rank  fav_index 
abc1 0  10    2  (null) 
abc1 1  25    1  1 
abc2 0  5    1  0 
abc3 0  -20   1  0 

結果は、私が質問に記載されたものとは若干異なっている、しかし、各IDのfav_indexがありますこれは私が本当に必要なものです。これが誰かを助けるかもしれないことを望みます。乾杯。