2016-07-06 2 views
0

У меня есть две таблицы services и service_requests. service_requests стол имеет внешний ключ service_id ссылка services таблица.CakePHP 3: выберите данные из нескольких таблиц

я должен выбрать данные из services и service_requests где services.id = service_requests.service_idORDER 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........ Обе таблицы не связаны с контроллером, я использую в.

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) из

$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-запроса.

ответ

0

Это может быть достигнуто с помощью таблицы объединения

Ваш ServicesTable:

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

Ваш RequestsTable:

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

+0

Мне нужно сгруппировать результат с помощью 'ServiceRequests.service_id' и сортировать по' COUNT (ServiceRequests.service_id) DESC', но это не работает при добавлении 'group()', а также ahve для выбора только тех 'сервисов' которые находятся в 'service_requests' –

+0

попробуйте этот код: $ query = $ this-> Services-> find ('all', array ('содержать' => array ('Requests'))) \t \t -> group (' Requests.service_id ') \t \t -> заказ (массив (' Requests.service_id '=>' DESC ')) \t \t -> предел (2); – pradeep

+0

это дает ошибку как 'Ошибка: SQLSTATE [42S22]: Столбец не найден: 1054 Неизвестный столбец 'Requests.service_id' в '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' –

0

свяжите таблицы вместе, а затем получите доступ к связанным данным через службы $ service_requests->.

Это самый чистый и простой способ сделать это.

Смотрите это для того, как связать их вместе :) http://book.cakephp.org/3.0/en/orm/associations.html

+0

У службы ServiceTable уже есть 'hasMany' ассоциация с' ServiceRequests' и 'ServiceRequestsTable' имеет ассоциацию' принадлежит To' с 'Servises' –

+0

, тогда вы можете называть ее, как я сказал, с помощью сервисов service-> requests-> без необходимости $ servicesTable = TableRegistry :: get ('services'); Просто найдите запрос с функцией find() и отлаживайте его. вы увидите, что связанные объекты находятся в массиве. debug ($ service_req-> find() -> где (PUTCONDITIONHERE)); –

+0

Я использую '$ servicesTable = TableRegistry :: get ('Services);' потому что я не использую его в 'ServiceController.php'. Я использую модель' Services' в другом контроллере, который не связан с ' Службы 'или' ServiceRequests' –

0

Прежде всего, используйте select() в запросе cakePHP, тогда find ('all') не требуется, поэтому find() должно быть достаточно. Затем, я думаю, что ваша проблема с выполнением может быть решена путем размещения -> execute(); в конце запроса. Он не часто используется, но иногда помогает.

Смежные вопросы