【发布时间】:2015-12-17 17:18:20
【问题描述】:
在使用 PostgreSQL 9.3.10 的游戏中,一些玩家支付了“VIP 身份”的费用,这由包含未来日期的 vip 列指示:
# \d pref_users
Column | Type | Modifiers
------------+-----------------------------+--------------------
id | character varying(32) | not null
first_name | character varying(64) | not null
last_name | character varying(64) |
vip | timestamp without time zone |
玩家还可以通过将 nice 列设置为 true、false 或将其保留为 null 来评价其他玩家:
# \d pref_rep
Column | Type | Modifiers
-----------+-----------------------------+-----------------------------------------------------------
id | character varying(32) | not null
author | character varying(32) | not null
nice | boolean |
我通过发出以下 SQL JOIN 语句来计算 VIP 玩家的“声誉”:
# select u.id, u.first_name, u.last_name,
count(nullif(r.nice, false))-count(nullif(r.nice, true)) as rep
from pref_users u, pref_rep r
where u.vip>now()and u.id=r.id group by u.id order by rep asc;
id | first_name | last_name | rep
-------------------------+--------------------------------+--------------------
OK413274501330 | ali | salimov | -193
OK357353924092 | viktor | litovka | -137
DE20287 | sergej warapow |
我的问题是:
如何找到所有负面评价的球员,谁评价过其他球员?
(背景是我添加了对其他人进行评分的可能性 - 对所有 VIP 玩家。在此之前,只有获得正面评价的玩家才能对其他人进行评分)。
我尝试了以下方法,但得到以下错误:
# select count(*) from pref_rep r, pref_users u
where r.author = u.id and u.vip > now() and
u.id in (select id from pref_rep
where (count(nullif(nice, false)) -count(nullif(nice, true))) < 0);
ERROR: aggregate functions are not allowed in WHERE
LINE 1: ...now() and u.id in (select id from pref_rep where (count(null...
^
更新:
我现在正在尝试使用临时表 -
首先我用所有负面评价的 VIP 用户填充它,这很好用:
# create temp table my_temp as select u.id, u.first_name, u.last_name,
count(nullif(r.nice, false))-count(nullif(r.nice, true)) as rep
from pref_users u, pref_rep r
where u.vip>now() and u.id=r.id group by u.id;
SELECT 362
但是我的 SQL JOIN 返回了太多相同的行,我找不到那里缺少什么条件:
# select u.id, u.first_name, u.last_name
from pref_rep r, pref_users u, my_temp t
where r.author=u.id and u.vip>now()
and u.id=t.id and t.rep<0;
id | first_name | last_name
-------------------------+--------------------------------+----------------------------
OK400153108439 | Vladimir | Pelix
OK123283032465 | Edik | Lehtik
OK123283032465 | Edik | Lehtik
OK123283032465 | Edik | Lehtik
OK123283032465 | Edik | Lehtik
OK123283032465 | Edik | Lehtik
OK123283032465 | Edik | Lehtik
同样的问题(相同数据的多行)我得到的语句:
# select u.id, u.first_name, u.last_name
from pref_rep r, pref_users u
where r.author = u.id and u.vip>now()
and u.id in (select id from my_temp where rep < 0);
我想知道这里可能缺少什么条件?
【问题讨论】:
-
聚合函数必须放在HAVING子句中,不能放在WHERE子句中。
-
尝试
select id from pref_rep having (count(nullif(nice, false)) -count(nullif(nice, true))) < 0;不幸的是:ERROR: column "pref_rep.id" must appear in the GROUP BY clause or be used in an aggregate function -
使用聚合时,SELECT 子句中的所有内容都必须具有聚合函数或位于 GROUP BY 子句中。您可能想花一些时间在 SQL 教程上。
标签: sql postgresql join postgresql-9.3 nullif