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.