LINUX.ORG.RU

sql для подсчета кармы

 


0

2

Недавно появилась такая задачка: есть таблица с изменениями кармы пользователя. В таблицу добавляются записи вида: (id, user_id, , direction), где id - идентификатор записи, user_id - идентификатор пользователя, direction - направление изменения кармы может быть up или down. Нужно посчитать текущую карму для некоторого заданного пользователя.

Все бы хорошо, но есть одно условие - карма не может опускаться ниже нуля, то есть например для записей вида:

id  user_id  direction
1   1        up
2   1        up
3   1        down

для пользователя с user_id=1 карма будет равна 1, но для записей

id  user_id  direction
1   1        down
2   1        up
3   1        down

для пользователя с user_id=1 карма будет равна нулю, так как первая запись не считается.

То есть если описать алгоритм подсчета кармы - он будет примерно следующий

  • инициализируем переменную карма=0
  • идем по каждой записи:
    • если direction == up - прибавляем к текущему значению кармы единицу
    • если direction == down
      • если текущее значение кармы > 0 - вычитаем из него единицу
      • если текущее значение кармы == 0 - ничего не делаем

никак не пойму, можно ли и если можно то как оформить данный алгоритм в виде sql запроса (база postgresql 9.2, если это имеет значение)

Но зачем себе лишний раз жизнь усложнять?

TERRANZ ★★★★
()

Аналитикой можно что угодно посчитать. Можно в лоб считать через lag. Можно сделать так - внутренним запросом считаем текущую набегающую сумму sum1, внешним запросом считаем обычную по direction для строчек, у которых sum1 неотрицательна.

belkabelka
()
Ответ на: комментарий от anonymous

sum не прокатит, к примеру у нас +1 -1 -1 +1 +1 по сумме получится 1, а по алгоритму 2, потому что когда пришел второй минус, то карма была меньше нуля и ниже упасть не могла

Goganchic ★★
() автор топика
Ответ на: комментарий от belkabelka

можно пример с внутренним запросом в виде sql, а то я не совсем понял идею

Goganchic ★★
() автор топика
Ответ на: комментарий от ziemin

с триггером и хранимкой можно, да, но мне интересно, можно ли такое сделать именно одним sql запросом (пусть и с вложенностью, пусть небыстрый)

Goganchic ★★
() автор топика
Ответ на: комментарий от Goganchic

Не хранимкой, а табличкой. И будет один запрос: обновить значение для юзера 1. А триггер будет смотреть по твоим условиям и, в случае изменений писать в историю.

ziemin ★★
()

а не приходило в голову сделать вполне логичную отрицательную кармочку?

arkhnchul ★★
()

direction - направление изменения кармы может быть up или down.

шта bool уже не в моде? О_О

bhfq ★★★★★
()
Ответ на: комментарий от bhfq

direction - направление изменения кармы может быть up или down.

шта bool уже не в моде? О_О

Не каждая переменная с двумя возможными значениями - булева. Более того, каждый раз, когда я вижу, что для доменно не булевой переменной автор использовал bool вместо enum, хочется ударить его по пальцам, да по-сильнее.

yoghurt ★★★★★
()

на уровне идеи: добавить поле «текущая карма» (или сделать соотв.view) и считать как нарастающую сумму.

зы. вообще это задача прикладного уровня - на sql итог зависит от порядка выборки (сортировки по id);

зы2: поле «текущая карма» всё равно надо добавлять - иначе подзадача «как изменилась карма юзера за период» неразрешима без полной выборки

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

да, зависит от сортировки, считаем что чем больше id чем позднее создана запись

зы2: поле «текущая карма» всё равно надо добавлять - иначе подзадача «как изменилась карма юзера за период» неразрешима без полной выборки

да, пусть будет полная перевыборка, вот я хочу запрос сделать именно на эту полную перевыборку

p.s. запрос хочу из чистого интереса, пока что никто так и не ответил как сделать :(

Goganchic ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.