0

SQLテーブルに2つの肯定的な評価を持つユーザーDE9013があります。

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

そして、公正な評価と良い評価の合計は、予想どおり4つです。

# 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を超える完了したゲームをプレイし、評価(fair + nice)が30を超えるすべてのユーザーを検索しようとしている、以下のリストでユーザー9013を取得するのはなぜですか?

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

CentOS 5.7/64ビットでPostgreSQL8.4.7を使用する

4

1 に答える 1

1

最初のクエリでは、pref_repからのみ選択しています。2番目のクエリでは、pref_repをpref_matchに結合します。これは、表面上は多対多の関係にあります。特定のユーザーの場合、pref_matchのすべての行がすべての行pref_repに結合されます。たとえば、ユーザー9013のpref_matchに2行、pref_repに10行がある場合、20行が返されます。これが、pref_matchからのカウントが、結合なしよりも結合ありの方が多い理由です。

2つのテーブルをユーザーごとに個別に集計してから、結果を結合することをお勧めします。このようなものが機能するはずです:

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 
;
于 2011-04-13T07:04:15.207 に答える