Utiliser des fonctions d'agrégation dans un HAVING
clause est tout à fait légale, puisque HAVING
élimine les lignes de groupe. Le comptage conditionnel peut être réalisé soit en utilisant la propriété NULL
s ne compte pas :
count(expression)
... nombre de lignes d'entrée pour lesquelles la valeur de l'expression n'est pas nulle
ou si vous utilisez PostgreSQL 9.4 ou version ultérieure, avec l'agrégat FILTER
clause :
count(*) FILTER (WHERE something > 0)
Vous pouvez également utiliser une somme de uns (et de zéros).
PostgreSQL>=9.4 et SQLAlchemy>=1.0.0
Utilisation d'une fonction d'agrégation filtrée :
.having(func.count(1).filter(Question.accepted) >
func.count(1).filter(not_(Question.accepted)))
Ancien PostgreSQL et/ou SQLAlchemy
L'analogue SQL pour "if" est soit CASE
expression ou dans ce cas nullif()
une fonction. Les deux peuvent être utilisés avec le fait que NULL
s ne compte pas :
from sqlalchemy import case
...
.having(func.count(case([(Question.accepted, 1)])) >
func.count(case([(not_(Question.accepted), 1)])))
ou :
.having(func.count(func.nullif(Question.accepted, False)) >
func.count(func.nullif(Question.accepted, True)))
Utilisation de nullif()
peut être un peu déroutant car la "condition" est ce que vous ne faites pas vouloir compter. Vous pourriez concevoir une expression qui rendrait la condition plus naturelle, mais c'est laissé au lecteur. Ces 2 solutions sont plus portables, mais par contre le FILTER
La clause est standard, mais pas largement disponible.