我很难根据总和限制查询结果。示例代码:
$rows = Entry::find()
->section('cities')
->select('state')
->having("sum(case when covered = '1' then 1 else 0 end) = 0")
->asArray()
->all();
我只想选择0个城市“覆盖”的州。在“having”行上运行代码似乎被忽略了(它包括零和非零情况)。我试着用“where”代替“having”,但结果出现了一个异常——“组函数的使用无效”。我认为“拥有”是正确的方法,但是我犯了一个新手的错误——有什么建议吗?
/更新1/
谢谢@scaisedge和@angelm的提示-- groupBy
有帮助,但仍然没有按预期工作。似乎“拥有”一词仍然被忽视。修改代码:
$test = Entry::find()
->section('cities')
->select(['state', 'covered', "sum(case when covered = '1' then 1 else 0 end) as numCovered"])
->groupBy('state')
->having("sum(case when covered = '1' then 1 else 0 end) = 0")
->asArray()
->all();
我记录以下结果:
{state: "AL", covered: "0", numCovered: "0"}
{state: "AK", covered: "0", numCovered: "0"}
{state: "CA", covered: "1", numCovered: "19"}
{state: "CO", covered: "0", numCovered: "0"}
...
如上所示,当numcovered显然不是0时,状态(ca)也包括在内。
我还尝试了以下“having”代码(我假设是相同的): ->having("numCovered = 0")
/更新2/
使用@cpalmer建议的简化测试用例仍然会导致“ca”被选中,尽管有 numCovered = 19
. 我现在想知道这是否是craft cms的一个特性,因为我的查询似乎是正确的?
$test = Entry::find()
->section('cities')
->select('state')
->groupBy('state')
->having("sum(case when covered = '1' then 1 else 0 end) = 0")
->asArray()
->all();
有没有一种方法可以不用 having
?
/更新3/
正如@pocketrocket发布的db fiddle所建议的,我的sql应该可以工作。转储原始sql表明 having
忽略行。这个问题很可能与我对环境缺乏了解有关。
5条答案
按热度按时间iyr7buue1#
首先:我完全支持@olivier,您应该将问题的sql部分与体系结构本身分离。对于sql部分,让其他人知道您使用的是哪个数据库或sql方言(mysql、postgresql、mssql…)很重要。
我猜是的
MySQL
您正在使用什么:这两种方法实际上都应该起作用,按照user126587的建议,重复querypart中的have或按名称引用它如果两者都不起作用,而你又不想工作
having
也许你可以实现一个subselect?你可以在这里玩:db fiddle link
34gzjxbg2#
尝试为state添加groupby()
l7wslrjt3#
请尝试从所选列中删除“covered”。在某些sql数据库中,对数据进行分组时,如果select语句中有一列不在GROUPBY语句或聚合中,则可能会导致错误。在你的情况下,我认为这篇专栏文章造成了意想不到的结果。如果你真的想包含它,把它放到一个聚合中并给它取别名,比如
'MAX(covered) as covered'
```$test = Entry::find()
->section('cities')
->select(['state', "sum(case when covered = '1' then 1 else 0 end) as numCovered"])
->groupBy('state')
->having("sum(case when covered = '1' then 1 else 0 end) = 0")
->asArray()
->all();
rdlzhqv94#
尝试输入having部分“numcovered=0”。
s2j5cfk05#
我猜你忘记了having子句中0的一个引号。