如何比较条件中的两个字段/列?

Sam*_*aye 2 mysql cakephp query-builder cakephp-3.x

我正在努力弄清楚如何使子查询工作.

想象一下,我有:

    $schools
        ->select($this->Schools)
        ->select([
            'pupilcount' => $this->Pupils
                ->find()
                ->select([
                    $this->Pupils->find()->func()->count('*')
                ])
                ->where([
                    'Pupils.school_id' => 'Schools.id', 

                ]),
Run Code Online (Sandbox Code Playgroud)

我遇到的问题(我认为)Schools.id总是为0,因此计数返回为0.我可以取出Pupils连接并显示那里的学生.

我尝试更改我的代码以添加:

->select(['SCID' => 'Schools.id'])
Run Code Online (Sandbox Code Playgroud)

并引用在子查询但不起作用的情况下,它总是会返回0 pupilcount.

我在这做错了什么?

ndm*_*ndm 5

每当遇到查询问题时,请检查实际生成的查询(例如使用DebugKit).除非是表达式对象,否则条件的右侧将始终作为参数绑定,即您将与字符串文字进行比较:

Pupils.school_id = 'Schools.id'
Run Code Online (Sandbox Code Playgroud)

通常,为了正确的自动引用兼容性,列名应该是标识符表达式.虽然左侧将自动正确处理,但右侧需要手动处理.

在您的特定情况下,您可以轻松利用QueryExpression::equalFields(),这正是您正在尝试做的事情,比较字段/列:

->where(function (\Cake\Database\Expression\QueryExpression $exp, \Cake\ORM\Query $query) {
    return $exp->equalFields('Pupils.school_id', 'Schools.id');
})
Run Code Online (Sandbox Code Playgroud)

也可以通过简单地实例化它们来手动创建标识符表达式:

->where([
    'Pupils.school_id' => new \Cake\Database\Expression\IdentifierExpression('Schools.id')
])
Run Code Online (Sandbox Code Playgroud)

最后,您还可以始终传递单个字符串值,该值基本上作为原始SQL插入到查询中,但在这种情况下,标识符不会受到自动标识符引用的影响:

->where([
    'Pupils.school_id' => $query->identifier('Schools.id')
])
Run Code Online (Sandbox Code Playgroud)

也可以看看

  • @Sammaye本手册不包括完整的API,而是涵盖一般概念和最相关的主题.如果你知道添加条件如何工作的一般概念,那么在检查QueryExpression API时你会发现这一点(如果Cookbook中的示例使用正确的类型提示以支持IDE完成/检查,那么它就不会受到影响) .如果您了解我个人的发现,我总是在使用之前研究API文档和源代码,而在CakePHP的情况下,我也是一个偶然的贡献者,所以我现在已经深入研究了源代码. (2认同)