如何在 QueryExpression::addCase() 中使用表列而不是变量

Posted

技术标签:

【中文标题】如何在 QueryExpression::addCase() 中使用表列而不是变量【英文标题】:How to use the table columns instead of variables in QueryExpression::addCase() 【发布时间】:2015-07-24 08:39:23 【问题描述】:

在 Cakephps 的新 ORM 中,您可以使用 QueryBuilder 构建(理论上)任何查询。

我想根据另一个值选择两列之一的值。在常规查询中,可以按如下方式完成:

SELECT IF(from_id = 1, to_id, from_id) AS other_id FROM messages;

我正在尝试使用 QueryBuilder 和 QueryExpression::addCase() 归档相同的查询

$messagesQuery = $this->Messages->find('all');
$messagesQuery->select([
    'other_id' => $messagesQuery->newExpr()->addCase(
        $messagesQuery->newExpr()->add(['from_id' => $this->authUser->id]),
        ['to_id', 'from_id'],
        ['integer', 'integer']
    )
]);

这不起作用,因为传递的值不是整数,而是包含整数的表列。

通过反复试验(再次使用方法add()),我得到了以下信息:

$messagesQuery = $this->Messages->find('all');
$messagesQuery->select([
    'other_id' => $messagesQuery->newExpr()->addCase(
        $messagesQuery->newExpr()->add(['from_id' => $this->authUser->id]),
        [
            $messagesQuery->newExpr()->add(['to_id']), 
            $messagesQuery->newExpr()->add(['from_id'])
        ],
        ['integer', 'integer']
    )
]);

这会产生以下查询:

SELECT (CASE WHEN from_id = 1 THEN to_id END) AS `other_id` FROM messages Messages

现在,ELSE 部分不见了,尽管 CakePHP book states:

只要 case 条件少于值,addCase 将自动生成 if .. then .. else 语句。

examples in the CakePHP book 在这种情况下不是很有帮助,因为它们只使用静态整数或字符串作为值,例如:

#SELECT SUM(CASE published = 'Y' THEN 1 ELSE 0) AS number_published, SUM(CASE published = 'N' THEN 1 ELSE 0) AS number_unpublished FROM articles GROUP BY published

$query = $articles->find();
$publishedCase = $query->newExpr()->addCase($query->newExpr()->add(['published' => 'Y']), 1, 'integer');
$notPublishedCase = $query->newExpr()->addCase($query->newExpr()->add(['published' => 'N']), 1, 'integer');

$query->select([
    'number_published' => $query->func()->sum($publishedCase),
    'number_unpublished' => $query->func()->sum($unpublishedCase)
])
->group('published');

有没有办法让addCase 方法将两个表列用作值,而不仅仅是静态值?

【问题讨论】:

【参考方案1】:

事实证明,在我之前的编辑中,我只比解决方案少了一个合乎逻辑的步骤。

作为CakePHP book correctly states:

只要 case 条件少于值,addCase 将自动生成 if .. then .. else 语句。

但要使其工作,条件和值都必须是一个数组,即使只有一个条件。 (CakePHP 书没有说明这一点。)

这段代码:

$messagesQuery = $this->Messages->find('all');
$messagesQuery->select([
    'other_id' => $messagesQuery->newExpr()->addCase(
        [
            $messagesQuery->newExpr()->add(['from_id' => $this->authUser->id])
        ],
        [
            $messagesQuery->newExpr()->add(['to_id']), 
            $messagesQuery->newExpr()->add(['from_id'])
        ],
        ['integer', 'integer']
    )
]);

这个查询的结果:

SELECT (CASE WHEN from_id = 1 THEN to_id ELSE from_id END) AS `other_id` FROM messages Messages

尤里卡

【讨论】:

以上是关于如何在 QueryExpression::addCase() 中使用表列而不是变量的主要内容,如果未能解决你的问题,请参考以下文章

如何在表单提交后保留文本(如何在提交后不删除自身?)

如何在异步任务中调用意图?或者如何在 onPostExecute 中开始新的活动?

在 Avkit 中如何使用这三行代码,以及如何将音乐静音”

如何在 JDBC 中启动事务?

如何在 Fragment 中调用 OnActivityResult 以及它是如何工作的?

如何使用 Firebase 在 Web 上托管 Flutter?它的效果如何?