sql >> Base de Datos >  >> RDS >> PostgreSQL

SQLAlchemy func.count en columna booleana

Usando funciones agregadas en un HAVING cláusula es muy legal, ya que HAVING elimina filas de grupos. El conteo condicional se puede lograr usando la propiedad que NULL s no cuentan:

count(expression) ... número de filas de entrada para las que el valor de expresión no es nulo

o si usa PostgreSQL 9.4 o posterior, con el agregado FILTER cláusula:

count(*) FILTER (WHERE something > 0)

También podría usar una suma de unos (y ceros).

PostgreSQL>=9.4 y SQLAlchemy>=1.0.0

Usando una función agregada filtrada:

.having(func.count(1).filter(Question.accepted) >
        func.count(1).filter(not_(Question.accepted)))

PostgreSQL y/o SQLAlchemy más antiguos

El análogo de SQL para "si" es CASE expresión o en este caso nullif() función. Ambos se pueden usar junto con el hecho de que NULL s no cuentan:

from sqlalchemy import case

...

.having(func.count(case([(Question.accepted, 1)])) >
        func.count(case([(not_(Question.accepted), 1)])))

o:

.having(func.count(func.nullif(Question.accepted, False)) >
        func.count(func.nullif(Question.accepted, True)))

Usando nullif() puede ser un poco confuso ya que la "condición" es lo que no quiero contar Podría idear una expresión que haría que la condición fuera más natural, pero eso queda para el lector. Estas 2 son soluciones más portátiles, pero por otro lado el FILTER La cláusula es estándar, aunque no está ampliamente disponible.