PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

SQLAlchemy func.count sur la colonne booléenne

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.