【问题标题】:Codeigniter Active Record / MySQL Query - group_by causes only one row to be returnedCodeigniter Active Record / MySQL Query - group_by 只返回一行
【发布时间】:2013-07-13 20:35:44
【问题描述】:

我有以下疑问:

$this->db
     ->select('SQL_CALC_FOUND_ROWS null as rows
        ,services.*
        ,service_categories.*
        ,categories.*
        ,table4.*', FALSE)
     ->from('services')
     ->where('services.user_id', $user_id)
     ->join('service_categories', 'service_categories.service_id = services.service_id')
     ->join('categories', 'categories.cat_id= service_categories.cat_id')
     ->join('table4', 'table4.service_id= services.service_id', 'left')
     ->group_by('services.service_id')
     ->order_by('services.service_id', 'DESC');

 $query = $this->db->get();

表格如下所示:

Table: services
------------------------------------------------
| service_id | other_service_columns | user_id |
-----------------------------------------------|
|     23     |       other data      |    14   |
|     24     |       other data      |    14   |
------------------------------------------------


Table: service_categories
---------------------------------------
| service_cat_id | cat_id | service_id|
---------------------------------------
|        1       |   924  |     23    |
|        2       |   863  |     23    |
|        3       |   506  |     24    |
|        4       |   510  |     24    |
---------------------------------------

Table: categories
---------------------
| cat_id | cat_name |
---------------------
|   924  | cleaning |
|   863  | washing  |
|   506  | drying   |
|   510  | scrubbing|
---------------------

表 4 可能没有任何结果,所以我正在做一个左连接。但是,当我按 service_id 分组时,我没有从“service_categories”和“categories”表中获取所有相关类别 - 查询中只返回一行。 group_concat 是答案吗?如果是这样,我不确定如何使用它来获得我需要的结果 - 即查询中返回的所有相关类别。请帮忙!

我需要能够通过使用 foreach 对其进行迭代来处理查询结果,以在视图中生成如下内容:

--------------------------------------------------------
| Service ID | Other Service Data | Service Categories |
--------------------------------------------------------
|     23     | Data for Service 23| cleaning, washing  |
|     24     | Data for Service 24| drying, scrubbing  |
--------------------------------------------------------

【问题讨论】:

    标签: mysql codeigniter activerecord group-by


    【解决方案1】:

    更新:根据您的 cmets 和更新后的问题,您的基本 SQL 查询可能看起来像

    SELECT s.*, q.categories, t4.*
      FROM services s LEFT JOIN
    (
      SELECT sc.service_id, GROUP_CONCAT(c.cat_name) categories
        FROM service_categories sc JOIN categories c 
          ON sc.cat_id= c.cat_id
       GROUP BY sc.service_id
    ) q ON s.service_id = q.service_id LEFT JOIN table4 t4
        ON s.service_id = t4.service_id
     WHERE s.user_id = ?
    

    样本输出:

    | SERVICE_ID | OTHER_SERVICE_COLUMNS | USER_ID |类别 | -------------------------------------------------- ----------------- | 23 |其他数据 | 14 |清洗、洗涤| | 24 |其他数据 | 14 |干燥、擦洗|

    这里是SQLFiddle演示

    现在是 CI 代码的可能版本

    $sql = "SELECT s.*, q.categories, t4.*
              FROM services s LEFT JOIN
            (
              SELECT sc.service_id, GROUP_CONCAT(c.cat_name) categories
                FROM service_categories sc JOIN categories c 
                  ON sc.cat_id= c.cat_id
               GROUP BY sc.service_id
            ) q ON s.service_id = q.service_id LEFT JOIN table4 t4
                ON s.service_id = t4.service_id
             WHERE s.user_id = $user_id";
    $query = $this->db->query($sql);
    foreach ($query->result() as $row) {
       ...
    }
    

    回答原问题: 恕我直言,您的查询存在几个问题

    1. 您将结果集限制为唯一带有WHERE 子句的service_id。因此GROUP BY services.service_idORDER BY services.service_id 毫无意义。 GROUP_BY 仅在您想将值打包到分隔字符串中并取回唯一行时才有意义。
    2. 您没有使用LIMIT,因此SQL_CALC_FOUND_ROWS 也没有意义。

    话虽如此,您的查询可能看起来像

    $result = $this->db
         ->select('services.*
            ,service_categories.*
            ,categories.*
            ,table4.*', FALSE)
         ->from('services')
         ->join('service_categories', 'service_categories.service_id = services.service_id')
         ->join('categories', 'categories.cat_id= service_categories.cat_id')
         ->join('table4', 'table4.service_id= services.service_id', 'left')
         ->where('services.service_id', $service_id)
         ->get();
    

    这里是SQLFiddle演示

    【讨论】:

    • SQL_CALC_FOUND_ROWS 可能与问题无关,但我在查询中使用它,因为我需要计算找到的结果的数量。我使用 $data['count'] = $this->db->query('SELECT FOUND_ROWS() count;')->row()->count; 将计数作为查询的一部分返回。但是,如果没有分组,则返回的行数等于 service_categories 的数量而不是服务的数量。实际上我在这个问题上也犯了一个错误 - 道歉 - 应该是 ->where('services.user_id', $user_id)
    • 不用第二次打数据库就可以得到count($result)返回的记录数。现在您可以编辑您的问题并根据您提供的示例数据显示您想要的输出吗?
    • 好的,谢谢您的帮助,我已经编辑了问题以显示所需的输出
    猜你喜欢
    • 2013-07-11
    • 2013-02-22
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    • 2011-10-08
    • 2012-11-29
    • 1970-01-01
    相关资源
    最近更新 更多