【问题标题】:SQL case query with DISTINCT in cakephp3 ORMcakephp3 ORM中带有DISTINCT的SQL案例查询
【发布时间】:2019-06-26 00:02:54
【问题描述】:

我正在尝试在 cakephp 3 中构建具有不同计数的案例查询。

这是 SQL 中的查询:

select COUNT(distinct CASE WHEN type = 'abc' THEN app_num END) as "count_abc",COUNT(distinct CASE WHEN type = 'xyz' THEN app_num END) as "count_xyz" from table;

目前,我做到了这一点:

$query = $this->find();

$abc_case = $query->newExpr()->addCase($query->newExpr()->add(['type' => 'abc']),' app_num','string');
$xyz_case = $query->newExpr()->addCase($query->newExpr()->add(['type' => 'xyz']),'app_num','string');


$query->select([
    "count_abc" => $query->func()->count($abc_case),
    "count_xyz" => $query->func()->count($xyz_case),
]);

但我无法在此代码中应用 distinct。

【问题讨论】:

    标签: sql cakephp orm cakephp-3.0 cakephp-3.6


    【解决方案1】:

    在函数中使用关键字一直是个问题,例如,请参阅此问题单:https://github.com/cakephp/cakephp/issues/10454

    这在 https://github.com/cakephp/cakephp/pull/11410 中有所改进,因此现在可以(错误)使用 DISTINCT 的函数表达式作为一种解决方法,即生成类似 DISTINCT(expression) 的代码,这是因为括号被忽略了,可以这么说,因为DISTINCT 不是一个函数!

    我不确定这是否有效,因为 SQL 规范明确允许像这样使用括号(也充当空格替代品),或者因为它是副作用,所以也许在依赖它之前检查一下!

    话虽如此,您可以使用链接 PR 中的解决方法,直到添加真正的聚合函数关键字支持,即执行以下操作:

    "count_abc" => $query->func()->count(
        $query->func()->DISTINCT([$abc_case])
    )
    

    这将生成类似于以下内容的 SQL:

    (COUNT(DISTINCT(CASE WHEN ... END)))
    

    【讨论】:

    • 这正在生成您提到的 SQL,但结果始终包含 "count_abc" = 1 或 "count_abc" = 0。是不是因为查询中有多余的括号?
    • @GauravNeema 嗯,这是一个不同的问题......如果示例代码实际上是您正在使用的代码,那么问题是您正在计算一个字符串,即app_num。如果这应该是一列,那么您需要将其作为标识符表达式传递,例如$query->identifier('app_num')。在第一个 case 语句的 app_num 字符串中也有一个空格。
    • 带有标识符的完整语句是什么?我从未使用过标识符。
    • @GauravNeema 只需传递显示的 sn-p 而不是 app_num 字符串。你也可以放弃第三个参数。
    猜你喜欢
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 2022-08-05
    • 2018-06-17
    • 1970-01-01
    • 2014-11-10
    • 2013-03-08
    相关资源
    最近更新 更多