Ein*_*din 3 python postgresql sqlalchemy
如何轻松计算特定列所在的行数和特定列所在的行true
数false
?
我无法(或可以?)运行带有count()的查询,因为我将此计数嵌入了having()子句中,例如:
.having(func.count(Question.accepted) >
func.count(not_(Question.accepted)))
Run Code Online (Sandbox Code Playgroud)
但是通过上述方法,该函数计算了不等式两侧的每一行。
我尝试过这样的事情
.having(func.count(func.if_(Question.accepted, 1, 0)) >
func.count(func.if_(Question.accepted, 0, 1)))
Run Code Online (Sandbox Code Playgroud)
但我得到一个错误
函数if(布尔值,整数,整数)不存在
(似乎它在postgresql中不存在)。
如何轻松计算column为true和false的行数?
Using aggregate functions in a HAVING
clause is very much legal, since HAVING
eliminates group rows. Conditional counting can be achieved either by using the property that NULL
s don't count:
count(expression)
... number of input rows for which the value of expression is not null
or if using PostgreSQL 9.4 or later, with the aggregate FILTER
clause:
count(*) FILTER (WHERE something > 0)
Run Code Online (Sandbox Code Playgroud)
You could also use a sum of ones (and zeros).
Using a filtered aggregate function:
.having(func.count(1).filter(Question.accepted) >
func.count(1).filter(not_(Question.accepted)))
Run Code Online (Sandbox Code Playgroud)
The SQL analog for "if" is either CASE
expression or in this case nullif()
function. Both of them can be used together with the fact that NULL
s don't count:
from sqlalchemy import case
...
.having(func.count(case([(Question.accepted, 1)])) >
func.count(case([(not_(Question.accepted), 1)])))
Run Code Online (Sandbox Code Playgroud)
or:
.having(func.count(func.nullif(Question.accepted, False)) >
func.count(func.nullif(Question.accepted, True)))
Run Code Online (Sandbox Code Playgroud)
Using nullif()
can be a bit confusing as the "condition" is what you don't want to count. You could device an expression that would make the condition more natural, but that's left for the reader. These 2 are more portable solutions, but on the other hand the FILTER
clause is standard, though not widely available.
归档时间: |
|
查看次数: |
2971 次 |
最近记录: |