我有一个用户 DE9013 ,在SQL表中有两个正面评级:
# select * from pref_rep where id='DE9013';
id | author | good | fair | nice | about | last_rated | author_ip
--------+--------+------+------+------+-------+----------------------------+---------------
DE9013 | DE9241 | t | t | t | | 2011-03-06 09:23:00.400518 | 97.33.154.43
DE9013 | DE9544 | t | t | t | | 2011-03-06 10:06:37.561277 | 97.33.35.54
(2 rows)
合理 + 漂亮评分的总和与预期的一样四:
# select
count(nullif(r.fair, false)) +
count(nullif(r.nice, false)) -
count(nullif(r.fair, true)) -
count(nullif(r.nice, true))
from pref_rep r where id='DE9013';
?column?
----------
4
(1 row)
我的问题是:为什么我在下面的列表中找到用户 9013 ,我试图找到所有玩过30多个已完成游戏且评分为的用户公平 + 好看)高于30?
# select substring(m.id from 3)::bigint, 3
from pref_match m, pref_rep r
where m.id=r.id and
m.id like 'DE%'
group by m.id
having (sum(m.completed) > 30 and
count(nullif(r.fair, false)) +
count(nullif(r.nice, false)) -
count(nullif(r.fair, true)) -
count(nullif(r.nice, true)) > 30) limit 3;
substring | ?column?
-----------+----------
9013 | 3
8692 | 3
7059 | 3
(3 rows)
将PostgreSQL 8.4.7与CentOS 5.7 / 64位一起使用
答案 0 :(得分:1)
在您的第一个查询中,您只是从pref_rep中选择。在第二个查询中,您将pref_rep加入pref_match,表面上是多对多的关系。对于给定用户,pref_match中的每一行都将连接到每行pref_rep。例如,如果用户9013在pref_match中有2行,在pref_rep中有10行,那么你将获得20行!这就是为什么来自pref_match的计数在连接时比没有连接时更高。
我建议你分别按用户聚合两个表,然后加入结果。这样的事情应该有效:
select substring(ma.id from 3)::bigint, 3
from (
select r.id
from pref_rep r
where r.id like 'DE%' --yuck!
group by r.id
having (count(nullif(r.fair, false)) +
count(nullif(r.nice, false)) -
count(nullif(r.fair, true)) -
count(nullif(r.nice, true)) > 30)
) ra
join (
select m.id
from pref_match m
where m.id like 'DE%' --yuck!
group by m.id
having sum(m.completed) > 30
) ma
on ra.id = ma.id
;