2011-04-12 47 views
0

我有一个用户DE9013与SQL表两个正评级:PostgreSQL的:having子句未正常工作

# 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) 

我的问题是:为什么会出现在列表中的用户是低,在那里我试图找到所有玩过超过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位

回答

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 
;