问题
I have a small Facebook card game where users can rate each other.
Those ratings are stored in a PostgreSQL 8.4.13 table pref_rep
as a boolean value nice
, which can be null too:
# \d pref_rep;
Table "public.pref_rep"
Column | Type | Modifiers
-----------+-----------------------------+-----------------------------------------------------------
id | character varying(32) | not null
author | character varying(32) | not null
nice | boolean |
comment | character varying(256) |
rep_id | integer | not null default nextval('pref_rep_rep_id_seq'::regclass)
Indexes:
"pref_rep_pkey" PRIMARY KEY, btree (id, author)
Check constraints:
"pref_rep_check" CHECK (id::text <> author::text)
Foreign-key constraints:
"pref_rep_author_fkey" FOREIGN KEY (author) REFERENCES pref_users(id) ON DELETE CASCADE
"pref_rep_id_fkey" FOREIGN KEY (id) REFERENCES pref_users(id) ON DELETE CASCADE
I would like to make those ratings visible as a pie chart on user avatars:
So I am trying the following -
First select a quotient (nice / nice + not nice) from pref_rep
:
# select id,
(count(nullif(nice, false)) - count(nullif(nice, true))) / count(nice) as rating
from pref_rep
where nice is not null
group by id;
id | rating
-------------------------+--------
DE10072 | -1
DE10086 | 0
DE10087 | 1
DE10088 | -1
DE10095 | 0
DE10097 | 1
DE10105 | 0
Why doesn't it print a 0-to-1 floating number here?
And then I am trying to store that quotient in the pref_users
table - because of performance reasons I want to do it by a nightly cronjob:
# update pref_users u
set rating = s.rating
from (
select
id,
count(nullif(nice, false)) - count(nullif(nice, true)) / count(nice) as rating
from pref_rep
where nice is not null
group by id
) s
where u.id = s.id;
UPDATE 25419
This completes quickly, but why are all rating
values in pref_users
are set to null?
回答1:
The rating:
select id,
coalesce(
(count(nice or null) - count(not nice or null))::float
/ count(nice)
, 0) as rating
from pref_rep
group by id;
count
does not count nulls. true or null
will return true
. false or null
will return null
. It is all casted to float
to make a float
return.
As to why your update only yields nulls I don't know. Post some sample data so we can play with it.
来源:https://stackoverflow.com/questions/17040692/calculate-a-quotient-in-one-table-and-store-it-in-another-table