首页 > 解决方案 > CakePHP 如何获取关联数据和 COUNT/GROUP BY

问题描述

我在使用 Cakephp 查询生成器时遇到了一些问题,并尝试获取我正在寻找的结果。我有三个表'Users'、'Items'、'Owns',其中 Owns 属于 'Users' 和 'Items'.... 用户可以拥有许多项目(以及许多相同的项目)。

所以我想返回用户的“拥有”项目以及计数......但是,每当我将计数添加到我的查询中时,我都会丢失相关的项目数据。

示例 - 这将返回用户数据以及关联的拥有数据和关联的项目数据,如查询下方所示

$owns = $this->Users->get($id, [
  'contain' => [
    'Owns' => function($q) { return $q->find('all')->group(['Owns.item_id']); },
    'Owns.Items'
  ],
]);

从这里生成的 SQL 是

SELECT 
  Owns.id AS Owns__id, 
  Owns.item_id AS Owns__item_id, 
  Owns.user_id AS Owns__user_id, 
  Items.id AS Items__id, 
  Items.name AS Items__name, 
  Items.description AS Items__description, 
  Items.created AS Items__created, 
  Items.modified AS Items__modified 
FROM 
  owns Owns 
  INNER JOIN items Items ON Items.id = (Owns.item_id) 
WHERE 
  Owns.user_id in (1) 
GROUP BY 
  Owns.item_id

数据结果如下所示:

'owns' => [
    'id' => (int) 1,
    'username' => 'myusername',
    'owns' => [
        (int) 0 => object(App\Model\Entity\Own) id:0 {
        'id' => (int) 2
        'item_id' => (int) 1
        'user_id' => (int) 1
            'item' => object(App\Model\Entity\Item) id:1 {
                'id' => (int) 1
                'name' => 'Item Name'
                'description' => 'Item Description'

但是,在“拥有”查询中,我想添加计数(即拥有的数量)。我可以通过使用此查询来获取计数,但随后我从结果中丢失了关联的项目对象。我尝试了很多不同的方法,但似乎总是如果我想使用 SQL 计数,我无法获得相关的数据。

$owns2 = $this->Users->get($id, [
  'contain' => [ 
    'Owns' => function($q) { return $q->select(['count' => $q->func()->count('Owns.id'),'Owns.id', 'Owns.user_id', 'Owns.item_id'])->group(['Owns.item_id']); },
    'Owns.Items'
  ],
]);

从这里生成的 SQL 是

SELECT 
  (COUNT(Owns.id)) AS count, 
  Owns.id AS Owns__id, 
  Owns.user_id AS Owns__user_id, 
  Owns.item_id AS Owns__item_id 
FROM 
  owns Owns 
  INNER JOIN items Items ON Items.id = (Owns.item_id) 
WHERE 
  Owns.user_id in (1) 
GROUP BY 
  Owns.item_id

数据结果如下所示:

'owns2' => [
    'id' => (int) 1,
    'username' => 'myusername',
    'owns' => [
        (int) 0 => object(App\Model\Entity\Own) id:36 {
        'count' => (int) 4
        'id' => (int) 2
        'user_id' => (int) 1
        'item_id' => (int) 1

任何有关如何将“计数”到第一个 $user 查询或关联项目到 $user2 的见解都将不胜感激。

标签: cakephpcakephp-4.x

解决方案


为了保留 $owns = find('all') 查询中返回的关联表的字段以及 SQL 计数函数,我需要将关联的字段添加到 select 语句中

$owns2 = $this->Users->get($id, [
  'contain' => [ 
    'Owns' => function($q) { return $q->select(['count' => $q->func()->count('Owns.id'),'Owns.id', 'Owns.item_id','Owns.user_id', 'Items.id', 'Items.collection_id','Items.name', 'Items.description'])->group(['Owns.item_id']); },
    'Owns.Items'
  ],

]);


推荐阅读