PostgreSQL:如何在周表中查找具有最大资金的 id
我有下表保存每周锦标赛的虚拟货币:
# select * from pref_money limit 5;
id | money | yw
----------------+-------+---------
OK32378280203 | -27 | 2010-44
OK274037315447 | -56 | 2010-44
OK19644992852 | 8 | 2010-44
OK21807961329 | 114 | 2010-44
FB1845091917 | 774 | 2010-44
(5 rows)
在列出用户的 PHP 脚本中,我需要知道谁是每周获胜者,以便我可以在他们的名字旁边显示奖牌。所以我正在尝试这个 SQL 语句:
# find the weekly winners
$sth = $db->prepare('select id from pref_money
where money in
(select max(money) from pref_money group by yw)');
$sth->execute();
while ($row = $sth->fetch(PDO::FETCH_ASSOC))
@$medals[$row['id']]++;
这大多数情况下有效,但有时当用户碰巧在某周内拥有与获胜者相同的金额(但不是最大金额)时,我会得到误报再过一周。
有谁知道如何更改 SQL 语句,以便真正只选择获胜者 ID?
当我尝试以下操作时,出现错误:
# select id, max(money) from pref_money group by yw;
ERROR: column "pref_money.id" must appear in the
GROUP BY clause or be used in an aggregate function
谢谢! Alex
更新:PostgreSQL 8.4.5 / CentOS 并且可能有联系:-)
I have the following table holding virtual money for weekly tournaments:
# select * from pref_money limit 5;
id | money | yw
----------------+-------+---------
OK32378280203 | -27 | 2010-44
OK274037315447 | -56 | 2010-44
OK19644992852 | 8 | 2010-44
OK21807961329 | 114 | 2010-44
FB1845091917 | 774 | 2010-44
(5 rows)
In my PHP script listing users, I need to know who has been a weekly winner, so that I can show medals near their names. So I'm trying this SQL statement:
# find the weekly winners
$sth = $db->prepare('select id from pref_money
where money in
(select max(money) from pref_money group by yw)');
$sth->execute();
while ($row = $sth->fetch(PDO::FETCH_ASSOC))
@$medals[$row['id']]++;
This mostly works, but sometimes I get false positives, when a user happens to have the same amount of money in some week (but not max there) as the winner in another week.
Does anybody have an idea how to change the SQL statement, so that really only winner ids are being selected?
When I try the following, I get an error:
# select id, max(money) from pref_money group by yw;
ERROR: column "pref_money.id" must appear in the
GROUP BY clause or be used in an aggregate function
Thank you!
Alex
UPDATE: PostgreSQL 8.4.5 / CentOS and there can be ties :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
哪个版本的 PostgreSQL?这对于 8.4 中引入的窗口函数来说很容易:
这在旧版本中几乎可以做到:
但是请注意,两个用户并列获得最大金钱的几周将在输出中显示两次。如果这确实是您想要的,您也可以使用窗口函数,使用
rank()
而不是row_number()
Which version PostgreSQL? This is easy with windowing functions introduced in 8.4:
This will just about do in older versions:
But observe that weeks where two users tie for the maximum money will be shown twice in the output. If that's actually what you want, you can do with with the windowing functions too, using
rank()
instead ofrow_number()
假设 PostgreSQL 8.4+,并且在给定的一周内没有人获得获胜者位置 - 这将列出每周获胜者:
如果可以有平局,请使用:
我包含了
yw
列,以防万一想要/需要按列过滤。Assuming PostgreSQL 8.4+, and no one ties for the winner position in a given week -- this will list the weekly winners:
If there can be ties, use:
I included the
yw
column, in case you want/need to filter by the column.