PostgreSQL отслеживает голоса в таблице?

У меня есть таблица с простым столбцом голосования вверх/вниз, который я изначально создал как логическое значение. true голос "за", false голос "против". Однако я не уверен, как использовать агрегатные функции для достижения такого результата запроса. Например, 5 строк true и 2 строки false должны равняться +3.

Я думаю, что мне нужно изменить столбец на smallint с +1 и -1. Это правильно? Есть ли лучший способ запросить что-то вроде этого?


person Xeoncross    schedule 12.03.2011    source источник
comment
Лично я бы предпочел решение «smallint». Это увеличит ваши строки на 1 байт, но ускорит подсчет запросов. (1 байт не имеет значения, только заголовок строки на диске составляет 24 байта)   -  person intgr    schedule 13.03.2011


Ответы (1)


Не нужно менять тип данных, просто используйте CASE, чтобы преобразовать его в -1 и 1, а затем просуммировать выражение:

SELECT sum(case when vote_column then 1 else -1 end)
FROM your_table

Чтобы правильно работать со значениями NULL, используйте следующее

SELECT sum(case vote_column 
              when true then 1 
              when false then -1 
              else 0 
           end)
FROM your_table
person a_horse_with_no_name    schedule 12.03.2011
comment
Или включить нули: sum(case vote_column when 1 then 1 when 0 then -1 else 0 end) - person Ben; 12.03.2011
comment
@Ben: нули все равно не будут учитываться, поскольку sum() пропускает нулевые значения - person a_horse_with_no_name; 12.03.2011
comment
Делается ли это быстрее, чем просто переход на smallint? У меня много записей, и я предпочел бы наиболее оптимальную настройку. - person Xeoncross; 12.03.2011
comment
@Xeoncross: я не думаю, что это повлияет на скорость. Если логические значения более удобны, придерживайтесь их. Если вы считаете, что целое число более удобно, используйте это. Но просто для подведения итогов нет необходимости избавляться от логического значения из-за производительности. - person a_horse_with_no_name; 12.03.2011
comment
@Xeoncross: если вы действительно беспокоитесь о производительности и вычисляете итоги намного больше, чем добавляете голоса, добавьте триггер для сохранения промежуточного итога в сводной таблице. Это добавит небольшой удар во время голосования, но резко сократит вычисления при подсчете голосов (что, возможно, является наиболее распространенным случаем доступа). - person mu is too short; 12.03.2011
comment
@Xeoncross, в выражении case a_horse_with_no_name нули преобразуются в ноль, поэтому они не будут пропущены, но не будут считаться голосами. Пропущенные значения NULL также могут вызывать предупреждения в некоторых СУБД, поэтому лучше обрабатывать их явно. - person Ben; 13.03.2011
comment
@Ben: хм, не включать нули - это то, как это должно работать в соответствии со стандартом SQL. Не могли бы вы сказать мне, какая СУБД не может справиться с этим должным образом? - person a_horse_with_no_name; 13.03.2011
comment
@ a_horse_with_no_name, ваш оператор case преобразует нулевые значения в -1, поэтому в SUM нет нулевых значений. Вы правы в отношении ANSI SQL, но пропущенные нули могут по-прежнему выдавать предупреждение в некоторых СУБД, включая SQL Server, в зависимости от действующих параметров ANSI SET. - person Ben; 13.03.2011