首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >布尔列上的SQLAlchemy func.count

布尔列上的SQLAlchemy func.count
EN

Stack Overflow用户
提问于 2016-05-19 16:13:05
回答 3查看 7.7K关注 0票数 6

如何简单地计算特定列为true的行数和false的行数?

我不能(或者我可以吗?)使用count()运行查询,因为我将此计数嵌入在having()子句中,如下所示:

代码语言:javascript
复制
.having(func.count(Question.accepted) >
        func.count(not_(Question.accepted)))

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

我试过这样的方法

代码语言:javascript
复制
.having(func.count(func.if_(Question.accepted, 1, 0)) >
        func.count(func.if_(Question.accepted, 0, 1)))

但我犯了个错误

如果(布尔值、整数、整数)不存在,则为

(它似乎不存在于postgresql中)。

如何容易地计算列为true和false的行数?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-05-19 20:58:55

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

count(expression) ...表达式值不为空的输入行数

或者,如果使用PostgreSQL 9.4或更高版本,则使用子句

代码语言:javascript
复制
count(*) FILTER (WHERE something > 0)

您也可以使用1之和(和0)

PostgreSQL >= 9.4和SQLAlchemy >= 1.0.0

使用过滤聚合函数

代码语言:javascript
复制
.having(func.count(1).filter(Question.accepted) >
        func.count(1).filter(not_(Question.accepted)))

旧PostgreSQL和/或SQLAlchemy

"if“的SQL模拟是表达式,或者在本例中是nullif()函数。这两种方法都可以与NULL不算在内的事实一起使用:

代码语言:javascript
复制
from sqlalchemy import case

...

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

或者:

代码语言:javascript
复制
.having(func.count(func.nullif(Question.accepted, False)) >
        func.count(func.nullif(Question.accepted, True)))

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

票数 9
EN

Stack Overflow用户

发布于 2016-05-19 20:54:23

您可以使用以下查询:

代码语言:javascript
复制
Session.query(func.sum(case([(Question.accepted == True, 1)], else_=0).label('accepted_number'))

而同一列的值为False,但条件为False。

或者,您可以使用窗口函数:

代码语言:javascript
复制
Session.query(func.count(Question.id).over(partition_by=Question.accepted), Question.accepted).all()

结果将包含两行(如果Question.accepted中只有两个可能的值),其中第一列是值的数目,第二列是“接受”列的值。

票数 5
EN

Stack Overflow用户

发布于 2020-03-12 03:21:05

大多数类型的SQL将布尔值存储为1位整数,并在它们上正确地调用和,从而给出正布尔/真行的数量。在您的例子中,您可以简单地做:

代码语言:javascript
复制
func.sum(Question.accepted)

如果SQL引擎以布尔值的形式返回布尔值之和(不确定有布尔值),则可以使用表达式函数cast()将其强制转换为整数,而不是使用func.count(case([(Question.accepted, 1)]))

代码语言:javascript
复制
func.sum(sqlalchemy.cast(Question.accepted, sqlalchemy.Integer))

最后,如果您希望将求和作为Python端的整数,则胁迫()可以完成以下任务:

代码语言:javascript
复制
sqlalchemy.type_coerce(func.sum(Question.accepted), sqlalchemy.Integer)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37328779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档