我有一个sql问题(在Redshift上),我需要根据index
列中的最大值为列id
中的每个ID获取列final_score
的值并将其放入新列fav_index
中的值。 score2
等于score1
index n
= index n + 1
的值,例如,id
= abc1
,index
= 0
和score1
= 10
score2
的值将是score1
的值,其中index
= 1
和值final_score
之间的差异是score1
和score2
之间的差异。
如果你查看下表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
的结果表应如下所示:
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
以下是从表score
生成表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
表story
如下:
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
)。我真的想避免编写这么长的脚本来获得我需要的一列额外信息。
有更好的方法吗?
谢谢!
更新:mysql中的答案也被接受。谢谢!
答案 0 :(得分:0)
花了更多时间在这上面并询问周围的人,我终于通过参考这个窗口函数文档找出了解决方案 - PostgreSQL https://www.postgresql.org/docs/9.1/static/tutorial-window.html
我基本上在顶部添加了2个select
语句,在最底部添加了1 x 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都被识别出来,这正是我真正需要的。希望这可以帮助某人。干杯