CakePHP 3:来自多个 table 的 select 数据
CakePHP 3 : select data from multiple table
我有两个 tables services
和 service_requests
。 service_requests
table 有外键 service_id
引用 services
table.
我必须 select 来自 services
和 service_requests
的数据,其中 services.id = service_requests.service_id
ORDER BY COUNT(service_requests.service_id) DESC
这就是我在我的控制器中所做的
$servicesTable = TableRegistry::get('services');
$featuredServices = $servicesTable->find('all')
->select(['ServiceRequests.service_id', 'count' => 'COUNT(ServiceRequests.service_id)'])
->select($servicesTable)
->join([
'table' => 'service_requests',
'alias' => 'ServiceRequests',
'conditions' => ['Services.id' => 'ServiceRequests.service_id'],
])
->group('service_id')
->order(['Count' => 'DESC'])
->limit(10);
$this->set('featuredServices', $featuredServices);
并打印为
if (!empty($featuredServices)):
foreach($featuredServices as $service):
echo $service->title;
endforeach;
endif;
但它不起作用。同样打印 echo $featuredServices;
仅打印 sql 字符串 SELECT.......
。两个 table 都与我正在使用的控制器无关。
EDIT 2
我想要这样的查询
SELECT ServiceRequests.service_id AS `ServiceRequests__service_id`, COUNT(ServiceRequests.service_id) AS `count`, Services.id AS `Services__id`, Services.service_category_id AS `Services__service_category_id`, Services.title AS `Services__title`, Services.description AS `Services__description` FROM services Services INNER JOIN service_requests ServiceRequests ON Services.id = ServiceRequests.service_id GROUP BY service_id ORDER BY Count DESC LIMIT 10
此 sql 查询在 phpMyAdmin
中的 运行 时工作正常,并且此查询由 debug($featuredServices)
of
生成
$featuredServices = $servicesTable->find('all')
->select(['ServiceRequests.service_id', 'count' => 'COUNT(ServiceRequests.service_id)'])
->select($servicesTable)
->join([
'table' => 'service_requests',
'alias' => 'ServiceRequests',
'conditions' => ['Services.id' => 'ServiceRequests.service_id'],
])
->group('service_id')
->order(['Count' => 'DESC'])
->limit(10);
这只会在调试时生成 sql 查询。我怎样才能执行此操作以便获得结果而不是 sql 查询。
link 将表放在一起,然后通过 $service_requests->services.
访问关联数据
这是最干净、最简单的方法。
查看此内容了解如何 link 他们在一起 :)
http://book.cakephp.org/3.0/en/orm/associations.html
这可以通过 table 协会
来实现
您的服务表:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('services');
$this->displayField('id');
$this->primaryKey('id');
======== use this line ===============
$this->hasOne('Requests'); // for one to one association
======== OR ===============
$this->hasMany('Requests'); // for one to many association
============ more specific ==========
$this->hasMany('Requests', array(
'foreignKey' => 'service_id'
));
}
您的请求表:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('requests');
$this->displayField('id');
$this->primaryKey('id');
========= add this line ============
$this->belongsTo('Services');
========= or more specific ============
$this->belongsTo('Services', array(
'foreignKey' => 'service_id',
'joinType' => 'INNER',
));
}
现在在控制器方法中:
public function test()
{
$this->loadModel('Services');
$query = $this->Services->find('all', array('contain' => array('Requests')))->limit(10);
//debug($query);
$services= $query->toArray();
debug($services);
$this->set('services', $services);
}
有关查找查询的更多具体信息,请参阅 link
http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html
以及有关 table 协会的更多信息,请参阅 link:
http://book.cakephp.org/3.0/en/orm/associations.html
首先,如果您在 cakePHP 查询中使用 select(),则 find('all') 不是必需的,因此 find() 应该足够了。
然后,我认为你的执行问题可以通过放置 ->execute(); 来解决。在查询结束时。它不经常使用,但有时会有所帮助。
我有两个 tables services
和 service_requests
。 service_requests
table 有外键 service_id
引用 services
table.
我必须 select 来自 services
和 service_requests
的数据,其中 services.id = service_requests.service_id
ORDER BY COUNT(service_requests.service_id) DESC
这就是我在我的控制器中所做的
$servicesTable = TableRegistry::get('services');
$featuredServices = $servicesTable->find('all')
->select(['ServiceRequests.service_id', 'count' => 'COUNT(ServiceRequests.service_id)'])
->select($servicesTable)
->join([
'table' => 'service_requests',
'alias' => 'ServiceRequests',
'conditions' => ['Services.id' => 'ServiceRequests.service_id'],
])
->group('service_id')
->order(['Count' => 'DESC'])
->limit(10);
$this->set('featuredServices', $featuredServices);
并打印为
if (!empty($featuredServices)):
foreach($featuredServices as $service):
echo $service->title;
endforeach;
endif;
但它不起作用。同样打印 echo $featuredServices;
仅打印 sql 字符串 SELECT.......
。两个 table 都与我正在使用的控制器无关。
EDIT 2
我想要这样的查询
SELECT ServiceRequests.service_id AS `ServiceRequests__service_id`, COUNT(ServiceRequests.service_id) AS `count`, Services.id AS `Services__id`, Services.service_category_id AS `Services__service_category_id`, Services.title AS `Services__title`, Services.description AS `Services__description` FROM services Services INNER JOIN service_requests ServiceRequests ON Services.id = ServiceRequests.service_id GROUP BY service_id ORDER BY Count DESC LIMIT 10
此 sql 查询在 phpMyAdmin
中的 运行 时工作正常,并且此查询由 debug($featuredServices)
of
$featuredServices = $servicesTable->find('all')
->select(['ServiceRequests.service_id', 'count' => 'COUNT(ServiceRequests.service_id)'])
->select($servicesTable)
->join([
'table' => 'service_requests',
'alias' => 'ServiceRequests',
'conditions' => ['Services.id' => 'ServiceRequests.service_id'],
])
->group('service_id')
->order(['Count' => 'DESC'])
->limit(10);
这只会在调试时生成 sql 查询。我怎样才能执行此操作以便获得结果而不是 sql 查询。
link 将表放在一起,然后通过 $service_requests->services.
访问关联数据这是最干净、最简单的方法。
查看此内容了解如何 link 他们在一起 :) http://book.cakephp.org/3.0/en/orm/associations.html
这可以通过 table 协会
来实现您的服务表:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('services');
$this->displayField('id');
$this->primaryKey('id');
======== use this line ===============
$this->hasOne('Requests'); // for one to one association
======== OR ===============
$this->hasMany('Requests'); // for one to many association
============ more specific ==========
$this->hasMany('Requests', array(
'foreignKey' => 'service_id'
));
}
您的请求表:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('requests');
$this->displayField('id');
$this->primaryKey('id');
========= add this line ============
$this->belongsTo('Services');
========= or more specific ============
$this->belongsTo('Services', array(
'foreignKey' => 'service_id',
'joinType' => 'INNER',
));
}
现在在控制器方法中:
public function test()
{
$this->loadModel('Services');
$query = $this->Services->find('all', array('contain' => array('Requests')))->limit(10);
//debug($query);
$services= $query->toArray();
debug($services);
$this->set('services', $services);
}
有关查找查询的更多具体信息,请参阅 link http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html
以及有关 table 协会的更多信息,请参阅 link: http://book.cakephp.org/3.0/en/orm/associations.html
首先,如果您在 cakePHP 查询中使用 select(),则 find('all') 不是必需的,因此 find() 应该足够了。 然后,我认为你的执行问题可以通过放置 ->execute(); 来解决。在查询结束时。它不经常使用,但有时会有所帮助。