Учтите это:
SELECT array_length('{}'::character varying(16)[],1);
Вывод NULL
для пустого массива.Кроме того, ваш abuse_history
может быть NULL
сам.Поэтому вам нужно что-то вроде этого:
SELECT *
FROM tips
ORDER BY (likes - dislikes - COALESCE(array_length(abuse_history,1) * 5, 0)) DESC;
РЕДАКТИРОВАТЬ после обратной связи:
Работает в PostgreSQL 9.0 , как показано в этой демонстрации:
CREATE TABLE tips
( tip_id bigserial NOT NULL,
tip text,
author text,
post_date bigint,
likers character varying(16)[],
dislikers character varying(16)[],
likes integer,
dislikes integer,
abuse_history character varying(16)[]
);
INSERT INTO tips (likes, dislikes, abuse_history)
VALUES(1,0, '{}')
,(1,0, '{}')
,(0,1, '{}')
,(0,0, '{}')
,(1,0, '{stinks!,reeks!,complains_a_lot}');
SELECT tip_id
, likes
, dislikes
, (likes - dislikes - COALESCE(array_upper(abuse_history,1) * 5,0)) as pop
, (likes - dislikes - array_upper(abuse_history,1) * 5) as fail_pop
FROM tips
ORDER BY (likes - dislikes - COALESCE(array_upper(abuse_history,1) * 5,0)) DESC;
Вывод:
tip_id | likes | dislikes | pop | fail_pop
--------+-------+----------+-----+----------
1 | 1 | 0 | 1 |
2 | 1 | 0 | 1 |
4 | 0 | 0 | 0 |
3 | 0 | 1 | -1 |
5 | 1 | 0 | -14 | -14