2011-04-12 85 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 
;