Używanie funkcji agregujących w HAVING klauzula jest bardzo legalna, ponieważ HAVING eliminuje wiersze grupy. Zliczanie warunkowe można osiągnąć za pomocą właściwości, która NULL nie liczą się:
count(expression) ... liczba wierszy wejściowych, dla których wartość wyrażenia nie jest pusta
lub jeśli używasz PostgreSQL 9.4 lub nowszego, z agregacją FILTER klauzula:
count(*) FILTER (WHERE something > 0)
Możesz również użyć sumy jedynek (i zer).
PostgreSQL>=9.4 i SQLAlchemy>=1.0.0
Używając filtrowanej funkcji agregującej:
.having(func.count(1).filter(Question.accepted) >
func.count(1).filter(not_(Question.accepted)))
Starszy PostgreSQL i/lub SQLAlchemy
Analogiem SQL dla „if” jest albo CASE wyrażenie lub w tym przypadku nullif() funkcjonować. Oba mogą być używane razem z tym, że NULL nie liczą się:
from sqlalchemy import case
...
.having(func.count(case([(Question.accepted, 1)])) >
func.count(case([(not_(Question.accepted), 1)])))
lub:
.having(func.count(func.nullif(Question.accepted, False)) >
func.count(func.nullif(Question.accepted, True)))
Używanie nullif() może być nieco mylące, ponieważ „warunek” jest tym, czego nie robisz chcesz liczyć. Można by wymyślić wyrażenie, które uczyniłoby stan bardziej naturalnym, ale to pozostawia się czytelnikowi. Te dwa rozwiązania są bardziej przenośne, ale z drugiej strony FILTER klauzula jest standardowa, choć nie jest powszechnie dostępna.