PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

SQLAlchemy func.count su colonna booleana

Utilizzo di funzioni aggregate in un HAVING la clausola è molto legale, poiché HAVING elimina le righe di gruppo. Il conteggio condizionale può essere ottenuto utilizzando la proprietà che NULL Non contano:

count(expression) ... numero di righe di input per le quali il valore di expression non è null

o se si utilizza PostgreSQL 9.4 o successivo, con l'aggregato FILTER clausola:

count(*) FILTER (WHERE something > 0)

Potresti anche usare una somma di uno (e zeri).

PostgreSQL>=9.4 e SQLAlchemy>=1.0.0

Utilizzando una funzione di aggregazione filtrata:

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

PostgreSQL e/o SQLAlchemy meno recenti

L'analogo SQL per "if" è CASE espressione o in questo caso nullif() funzione. Entrambi possono essere usati insieme al fatto che NULL Non contano:

from sqlalchemy import case

...

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

oppure:

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

Usando nullif() può creare un po' di confusione in quanto la "condizione" è ciò che non non fai vuoi contare. Potresti escogitare un'espressione che renderebbe la condizione più naturale, ma questa è lasciata al lettore. Queste 2 sono soluzioni più portatili, ma d'altra parte il FILTER la clausola è standard, anche se non ampiamente disponibile.