我有用户统计信息的表格。为简单起见,它看起来像这样:
id nick kills deaths 1 Misiek 25 20 2 Astma 22 18 3 4i60r 20 32 4 Heatseeker 45 45
要显示我需要查询的内容,我准备了工作SQL查询:
SELECT COUNT(id)+1 as `rank` FROM (SELECT * FROM (SELECT *, (kills/deaths) as kdr FROM `killerzy`) as b WHERE kdr > (SELECT (kills/deaths) as kdr FROM `killerzy` WHERE nick="4i60r")) as test
此查询的结果是:
rank 4
为了说明我如何计算kdr:
SELECT *, (kills/deaths) as kdr FROM `killerzy` WHERE 1
它产生:
id nick kills deaths kdr 1 Misiek 25 20 1.2500 2 Astma 22 18 1.2222 3 4i60r 20 32 0.6250 4 Heatseeker 45 45 1.0000
我的问题是: mysql或postgresql数据库是否具有现成功能,无需编写3个嵌套查询即可获得播放器的“排名”?我想的是:
SELECT ROW_NUMBER() FROM (SELECT (kills/deaths) as kdr FROM killerzy ORDER BY kdr DESC) WHERE nick = "4i60r"
它看起来比3个嵌套查询更合乎逻辑。
我看到很难理解这么简单的问题。这里有其他版本:MySQL或PostgreSQL是否具有可以返回结果集中哪个位置是行的函数,我需要它。像“GET_POSITION WHERE”之类的东西。 奇怪的是,当有人明白并回答好 - 简单的JOIN查询看起来很好并且执行速度很快时,我的问题就被搁置了。
答案 0 :(得分:4)
您似乎想要的是一个简单的排名查询。在MySQL的情况下,它就像是;
SELECT *, (kills/deaths) kdr, @rank := @rank + 1 rank
FROM `killerzy`, (SELECT @rank := 0) r
ORDER BY kdr DESC
在PostgreSQL中,您只需使用RANK() OVER()
;
SELECT *, 1.0*kills/deaths as kdr,
RANK() OVER (ORDER BY 1.0*kills/deaths DESC) rank
FROM killerzy;
可悲的是,SQLfiddle似乎很累,所以无法添加小提琴。
编辑:对于单个玩家,您可以使用LEFT JOIN
;
SELECT me.*, me.kills/me.deaths kdr, 1+COUNT(other.id) rank
FROM killerzy me
LEFT JOIN killerzy other
ON me.kills/me.deaths < other.kills/other.deaths
WHERE me.nick='4i60r';