如何在表格默认字段之外选择特定字段?

问题描述 投票:0回答:2

我希望使用 JOIN 从 CakePHP 中的表和视图中选择数据,如下所示:

$this->Annonces->find('all')
        ->where($arrFiltres)
        ->order($arrOrder)
        ->join([
            'table' => 'annonces_suivis',
            'alias' => 'AnnoncesSuivis',
            'conditions' => [...],      
        ]);

并且希望能够从第一个表和联合表的一些字段中选择所有字段,如下所示:

->select(['Annonces.*', 'AnnoncesSuivis.id']);

但这会创建一个错误的 SQL 查询。

php cakephp cakephp-3.0 query-builder
2个回答
15
投票
ORM 查询不支持

.*
,它会将其转换为

Annonces.* AS Annonces__*

这是无效的 SQL。它可以与较低级别的数据库查询(

Connection::newQuery()
)一起使用,它不会添加别名,但它不会返回实体,所以这可能不是您想要的。

参见 Cookbook > 数据库访问和 ORM > 数据库基础知识 > \Cake\Database\Connection::newQuery()

CakePHP 4+:使用
selectAlso()

您可以使用 selectAlso() 选择表上的所有字段,并选择一些其他字段:

$query = $articlesTable->find();
$query->selectAlso(['count' => $query->func()->count('*')]);

请参阅 Cookbook > 数据库访问和 ORM > 查询生成器 > 选择特定字段

传递一个表对象

从 CakePHP 3.1 开始,您可以将表对象传递给

Query::select()
,这将导致选择表的所有字段。

$this->Annonces
    ->find('all')
    ->select(['AnnoncesSuivis.id'])
    ->select($this->Annonces)
    ->join([
        'table' => 'annonces_suivis',
        'alias' => 'AnnoncesSuivis',
        'conditions' => [ /* ... */ ],     
    ])
    ->where($arrFiltres)
    ->order($arrOrder);

这样,

AnnoncesSuivis.id
字段以及
Annonces
的所有字段都会被选中。

请参阅 Cookbook > 数据库访问和 ORM > 查询生成器 > 从表中选择所有字段

从架构构建字段

这也是传递表对象也会在内部引起的,而且 CakePHP 也支持它 < 3.1.

$query = $this->Annonces->find('all');

$fields = $query->aliasFields(
    $this->Annonces->schema()->columns(),
    $this->Annonces->alias()
);

$query
    ->select(array_merge(['AnnoncesSuivis.id'], $fields))
    ->join([
        'table' => 'annonces_suivis',
        'alias' => 'AnnoncesSuivis',
        'conditions' => [ /* ... */ ],     
    ])
    ->where($arrFiltres)
    ->order($arrOrder);

这也适用于可以传递给

fields
Table::find()
选项,尽管在这种情况下您必须使用单独的查询对象,例如

$fields = $this->Annonces->query()->aliasFields(
    $this->Annonces->schema()->columns(),
    $this->Annonces->alias()
);

$this->Annonces->find('all', [
    'fields' => array_merge(['AnnoncesSuivis.id'], $fields)
    // ...
]);

使用
Query::autoFields()

在早期的 CakePHP 版本中,您还可以使用

Query::autoFields()
,当设置为
true
时,将自动包含主表的字段和可能的包含内容。

请参阅 Cookbook > 数据库访问和 ORM > 检索数据和结果集 > 传递条件以包含

自动选择所有字段是默认行为,直到您通过

Query::select()
设置字段,在这种情况下,您必须显式启用
Query::autoFields()

$this->Annonces
    ->find('all')
    ->select(['AnnoncesSuivis.id'])
    ->autoFields(true)
    ->join([
        'table' => 'annonces_suivis',
        'alias' => 'AnnoncesSuivis',
        'conditions' => [ /* ... */ ],     
    ])
    ->where($arrFiltres)
    ->order($arrOrder);

这应该为您提供所需的查询,但是如上所述,这仅适用于主表和包含项,如果您想包含手动连接表的所有字段,那么您必须一一指定它们。


1
投票

您还可以在实体中创建虚拟字段:

namespace App\Model\Entity;
use Cake\ORM\Entity;

class User extends Entity { 
    protected function _getFullName() {
       return $this->_properties['first_name'] . ' ' . $this->_properties['last_name']; 
    } 
}

echo $entity->full_name;

© www.soinside.com 2019 - 2024. All rights reserved.