python - bool 列上的 SQLAlchemy func.count

标签 python postgresql sqlalchemy

如何轻松计算特定列为 true 的行数和为 false 的行数?

我不能(或者我可以吗?)使用 count() 运行查询,因为我将这个计数嵌入到 having() 子句中,例如:

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

但是用上面的方法,函数计算不等式两边的每一行。

我试过这样的东西

.having(func.count(func.if_(Question.accepted, 1, 0)) >
        func.count(func.if_(Question.accepted, 0, 1)))

但是我得到一个错误

function if(boolean, integer, integer) does not exist

(postgresql好像没有)

如何轻松计算列为 true 和 false 的行数?

最佳答案

HAVING clause 中使用聚合函数非常合法,因为 HAVING 消除了组行。条件计数可以通过使用 NULL 不计数的属性来实现:

count(expression) ... number of input rows for which the value of expression is not null

或者如果使用 PostgreSQL 9.4 or later , 与 aggregate FILTER clause :

count(*) FILTER (WHERE something > 0)

你也可以使用 sum of ones (and zeros) .

PostgreSQL >= 9.4 和 SQLAlchemy >= 1.0.0

使用 filtered aggregate function :

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

较旧的 PostgreSQL 和/或 SQLAlchemy

“if”的 SQL 模拟是 CASE expression或者在这种情况下 nullif()功能。它们都可以与 NULL 不算在内的事实一起使用:

from sqlalchemy import case

...

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

或:

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

使用 nullif() 可能会有点困惑,因为“条件”是您不想计算的。您可以设计一个使条件更自然的表达式,但这留给了读者。这 2 个是更便携的解决方案,但另一方面,FILTER 子句是标准的,尽管没有广泛使用。

关于python - bool 列上的 SQLAlchemy func.count,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37328779/

相关文章:

mysql - 在 Mac 上安装 PostgreSQL ODBC 驱动程序以用于 MySQL Workbench 迁移向导

python - 如何在 sqlalchemy 中的变量中提供排序顺序?

python - 是否有用于 python 的数据库测试工具(如 sqlunit)?

Python 子进程在 .csv : 'unexpected eof' 上调用 bcp

python - python 中的科学记数法

python - 'numpy.ndarray' object has no attribute 'barh' 是什么意思,如何纠正?

java - Hibernate Projection 将结果返回为对象

arrays - 从多列创建 JSON 对象数组

python - Django - 应用程序特定的中间件

python - Pandas Python Groupby累计求和逆向