GROUP_CONCAT 选项中的条件

Condition in GROUP_CONCAT selection

我有 3 个 table,我要加入他们以获取一些数据。

-----------------
Table Name: users
-------------------------------
|user_id  | user_name |
-------------------------------
123      | abc
-------------------------------
223      | bcd
-------------------------------
323      | cde
-------------------------------

-----------------
Table Name: limit
-------------------------------
user_id  | limit_id
-------------------------------
123      | 1
-------------------------------
223      | 2
-------------------------------
323      | 3
-------------------------------
323      | 4
-------------------------------

-------------------------
Table Name: limit_setting
-------------------------------
limit_id | date_limit
-------------------------------
1        | 2016-09-29 12:00:00
-------------------------------
2        | 2016-09-28 12:00:00
-------------------------------
3        | 2016-09-27 12:00:00
-------------------------------
1        | 2016-09-27 12:00:00
-------------------------------
1        | 2016-09-24 12:00:00
-------------------------------
4        | 2016-09-25 12:00:00
-------------------------------
4        | 2016-09-26 12:00:00
-------------------------------

我需要得到这样的结果。我坚持使用日期列的 GROUP_CONCAT。 日期列应包含除最大日期以外的所有条目。如果 limit_setting table 中只有一个条目对应 limit_id,那么它不应该为该用户显示任何内容。 count_dates :它是 limit_setting table 中的条目数。


Desired output

----------------------------------------------------------------------
user_name | dates                                       | count_dates   
----------------------------------------------------------------------
abc       | 2016-09-27 12:00:00 , 2016-09-24 12:00:00   | 3
----------------------------------------------------------------------
bcd       |                                             | 1 
----------------------------------------------------------------------
cde       |                                             | 1 
-----------------------------------------------------------------------
cde       | 2016-09-26 12:00:00                         | 2 
-----------------------------------------------------------------------
SELECT PP.`user_name`, count(ESL.Limit_id) as count_dates,
  GROUP_CONCAT(ESL.date_limit SEPARATOR ',') as dates 
FROM users as PP INNER JOIN `limit` as PAL ON PP.Id = PAL.PlayerId
LEFT JOIN limit_setting as ESL ON ESL.LimitId = PAL.limitId 
GROUP BY PAL.limitId

另外我试过(没有返回)

SELECT ESL.date_limit, MAX(date_limit) as max_date, PP.`user_name`, count(ESL.Limit_id) as count_dates, 
  GROUP_CONCAT(ESL.date_limit SEPARATOR ',') as dates 
FROM users as PP INNER JOIN `limit` as PAL ON PP.Id = PAL.PlayerId 
LEFT JOIN limit_setting as ESL ON ESL.LimitId = PAL.limitId 
GROUP BY PAL.limitId
HAVING ESL.date_limit > max_date

我试过 Find_in_set 但不确定如何有效地使用它。

试试这个:

SELECT user_name,        
       CASE WHEN COUNT(*) > 1 
            THEN SUBSTRING_INDEX(GROUP_CONCAT(date_limit ORDER BY date_limit), 
                                 ',', COUNT(*) - 1) 
            ELSE ''
       END AS dates,             
       COUNT(*) AS count_dates
FROM users as PP 
INNER JOIN `limit` as PAL ON PP.user_id = PAL.user_id
LEFT JOIN limit_setting as ESL ON ESL.limit_id = PAL.limit_id
GROUP BY user_name

查询使用 SUBSTRING_INDEX 函数来获取 GROUP_CONCAT 返回的所有日期, 最后一个日期除外。在 GROUP_CONCAT 中使用 ORDER BY 我们可以将最大日期放在末尾,这样 SUBSTRING_INDEX 就会截断这个日期。

Demo here

我会使用子查询 return 每个限制的最大日期并将其连接回限制设置 table 以使用 [= 从 group_concat() 中消除最大日期12=]表达式:

SELECT 
    PP.`user_name`,
    count(ESL.Limit_id) as count_dates,
    GROUP_CONCAT(CASE
                     WHEN ESL.date_limit<>ls.maxdate THEN ESL.date_limit
                     ELSE ''
                 END SEPARATOR ',') as dates 
FROM users as PP
INNER JOIN `limit` as PAL ON PP.Id = PAL.PlayerId
LEFT JOIN limit_setting as ESL ON ESL.LimitId = PAL.limitId
LEFT JOIN (SELECT LimitId, MAX(date_limit) as maxdate
           FROM limit_setting
           GROUP BY LimitId
          ) ls ON ESL.LimitId=ls.LimitId
GROUP BY PP.`user_name`