如何仅为具有最大值的行获取GROUP_CONCAT

时间:2014-07-04 12:26:19

标签: mysql sql group-by

假设我们有一张表:

SELECT * FROM users_to_courses;
+---------+-----------+------------+---------+
| user_id | course_id | pass_date  | file_id |
+---------+-----------+------------+---------+
|       1 |         1 | 2014-01-01 |       1 |
|       1 |         1 | 2014-01-01 |       2 |
|       1 |         1 | 2014-02-01 |       3 |
|       1 |         1 | 2014-02-01 |       4 |
+---------+-----------+------------+---------+

架构:

CREATE TABLE `users_to_courses` (
  `user_id` int(10) unsigned NOT NULL,
  `course_id` int(10) unsigned NOT NULL,
  `pass_date` date NOT NULL,
  `file_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`user_id`, `course_id`, `pass_date`, `file_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

一个用户可以多次通过某个课程,每次通过多个证书都可以生成。 user_idcourse_id存储指向用户和课程表的链接。 file_id - 到文件表,其中存储有关证书文件的信息。

在我们的示例中,用户#1已经两次通过课程#1,每次颁发2个证书:共4个记录。

如何获取此数据:for user_id = 1 for each course get MAX(pass_date)和所有附加到此日期的文件。到目前为止,我只能得到这个:

SELECT
    users_to_courses.course_id,
    MAX(users_to_courses.pass_date) AS max_passed_date,
    GROUP_CONCAT(users_to_courses.file_id SEPARATOR ',') AS files   
FROM
    users_to_courses
WHERE
    users_to_courses.user_id=1
GROUP BY
    users_to_courses.course_id;

+-----------+-----------------+---------+
| course_id | max_passed_date | files   |
+-----------+-----------------+---------+
|         1 | 2014-02-01      | 1,2,3,4 |
+-----------+-----------------+---------+

我需要这个:

+-----------+-----------------+---------+
| course_id | max_passed_date | files   |
+-----------+-----------------+---------+
|         1 | 2014-02-01      |   3,4   |
+-----------+-----------------+---------+

我认为,这需要复合GROUP BY。

fiddle

1 个答案:

答案 0 :(得分:1)

尝试以下查询首先获取所有记录的最大日期,然后我们只能加入外部查询中的那些记录。您可以通过添加group by utc.user_id

为多个用户使用相同的查询
SELECT
    utc.course_id,
    mdt.maxDate AS max_passed_date,
    GROUP_CONCAT(utc.file_id SEPARATOR ',') AS files
FROM
    users_to_courses utc
    join
(SELECT MAX(pass_date) AS maxDate, course_id cId, user_id uId
        FROM users_to_courses GROUP BY user_id, course_id) AS mdt
ON
    mdt.uId = utc.user_id
AND
    mdt.cId = utc.course_id
AND 
    mdt.maxDate = utc.pass_date
WHERE
    utc.user_id=1
GROUP BY
    utc.course_id;