【问题标题】:CakePHP 3 : select data from multiple tableCakePHP 3:从多个表中选择数据
【发布时间】:2016-07-06 07:26:29
【问题描述】:

我有两张桌子servicesservice_requestsservice_requests 表有外键 service_id 引用 services 表。

我必须从servicesservice_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.......。这两个表都没有与我正在使用的控制器相关联。

编辑 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)生成的

$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 查询。

【问题讨论】:

    标签: php mysql cakephp cakephp-3.2


    【解决方案1】:

    这可以通过表关联来实现

    您的服务表:

    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);
    } 
    

    有关查找查询的更多具体信息,请参阅链接 http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html

    以及有关表关联的更多信息,请参见链接: http://book.cakephp.org/3.0/en/orm/associations.html

    【讨论】:

    • 我必须按ServiceRequests.service_id 对结果进行分组并按COUNT(ServiceRequests.service_id) DESC 排序,但这在添加group() 时不起作用,并且只能选择service_requests 中的services
    • 试试这个代码: $query = $this->Services->find('all', array('contain' => array('Requests'))) ->group('Requests. service_id') ->order(array('Requests.service_id' => 'DESC')) ->limit(2);
    • 这给出了Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Requests.service_id' in 'group statement' SQL CODE 的错误:SELECT Services.id AS 'Services__id', Services.service_category_id AS 'Services__service_category_id', Services.title AS 'Services__title', Services.description AS 'Services__description', Services.created AS 'Services__created' FROM services Services GROUP BY Requests.service_id ORDER BY Requests.service_id DESC LIMIT 2
    • 确保给定的表名和列名正确。与你的表匹配
    • 是的,他们是正确的。我也必须通过COUNTRequests.service_id 订购
    【解决方案2】:

    将表链接在一起,然后通过 $service_requests->services 访问相关数据。

    这是最干净、最简单的方法。

    请参阅此处了解如何将它们链接在一起 :) http://book.cakephp.org/3.0/en/orm/associations.html

    【讨论】:

    • ServicesTable 已经与 hasMany 关联 ServiceRequestsServiceRequestsTable 已关联 belongsToServises
    • 然后你可以像我说的那样用 $service->requests->services 调用它,而不需要 $servicesTable = TableRegistry::get('services');只需使用 find() 获取查找请求并对其进行调试。您将看到关联的对象在数组中。调试($service_req->find()->where(PUTCONDITIONHERE));
    • 我正在使用$servicesTable = TableRegistry::get('Services);,因为我没有在ServicesController.php 中使用它我在其他一些与Services ServiceRequests 都不相关联的控制器中使用Services 模型
    • okaya 然后没关系。它应该符合我的建议!祝你好运:)
    【解决方案3】:

    首先,如果你在 cakePHP 查询中使用 select(),那么 find('all') 就不是必需的,因此 find() 就足够了。 然后,我认为您的执行问题可以通过放置 ->execute(); 来解决。在查询结束时。它不经常使用,但有时会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-05
      • 1970-01-01
      相关资源
      最近更新 更多