Използване на агрегатни функции в HAVING
клаузата е много законна, тъй като HAVING
елиминира груповите редове. Условно броене може да се постигне или чрез използване на свойството NULL
s не се броят:
count(expression)
... брой входни редове, за които стойността на израза не е нула
или ако използвате PostgreSQL 9.4 или по-нова версия, с агрегатния FILTER
клауза:
count(*) FILTER (WHERE something > 0)
Можете също да използвате сбор от единици (и нули).
PostgreSQL>=9.4 и SQLAlchemy>=1.0.0
Използване на филтрирана агрегатна функция:
.having(func.count(1).filter(Question.accepted) >
func.count(1).filter(not_(Question.accepted)))
По-стари PostgreSQL и/или SQLAlchemy
SQL аналогът за "if" е или CASE
израз или в този случай nullif()
функция. И двете могат да се използват заедно с факта, че NULL
s не се броят:
from sqlalchemy import case
...
.having(func.count(case([(Question.accepted, 1)])) >
func.count(case([(not_(Question.accepted), 1)])))
или:
.having(func.count(func.nullif(Question.accepted, False)) >
func.count(func.nullif(Question.accepted, True)))
Използване на nullif()
може да бъде малко объркващо, тъй като "условието" е това, което не искам да преброя. Можете да създадете израз, който да направи условието по-естествено, но това остава за читателя. Тези 2 са по-преносими решения, но от друга страна FILTER
Клаузата е стандартна, но не е широко разпространена.