【问题标题】:MySQL - List members of the same group per rowMySQL - 每行列出同一组的成员
【发布时间】:2021-08-18 20:20:35
【问题描述】:

我有两张桌子

  1. tbl_Participants

    id group_name firstname lastname

  2. tbl_Groups

    id group_name

但我很难加入表格以显示以下布局。

Group Name | Member 1 | Member 2 | Member 3
  1. 名字和姓氏将显示在成员 col 下
  2. 每组最多 3 名参与者

此查询显示一个列表,但不在上面的布局中:

select gr.firstname, gr.lastname, gr.group_name 
from tbl_Participants gr inner join tbl_Group gr2 
ON gr.group_name = gr2.group_name 
order by group_name

【问题讨论】:

标签: php mysql


【解决方案1】:

对于 MySQl 8.0+,您可以使用 ROW_NUMBER() 窗口函数按字母顺序排列组内的成员名称,并在仅过滤每个组的前 3 个名称后使用条件聚合来获得您想要的结果:

SELECT group_name,
       MAX(CASE WHEN rn = 1 THEN name END) Member1,
       MAX(CASE WHEN rn = 2 THEN name END) Member2,
       MAX(CASE WHEN rn = 3 THEN name END) Member3
FROM (
  SELECT group_name, 
         CONCAT(lastname, ' ', firstname) name,
         ROW_NUMBER() OVER (PARTITION BY group_name ORDER BY lastname, firstname) rn
  FROM tbl_Participants
) t
WHERE rn <= 3
GROUP BY group_name

对于以前的版本,使用 GROUP_CONCAT()SUBSTRING_INDEX() 的聚合来拆分名称列表:

SELECT group_name,
       SUBSTRING_INDEX(names, ',', 1) Member1,
       CASE WHEN counter > 1 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(names, ',', 2), ',', -1) END Member2,
       CASE WHEN counter > 2 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(names, ',', 3), ',', -1) END Member3
FROM (
  SELECT group_name, 
         COUNT(*) counter,
         GROUP_CONCAT(CONCAT(lastname, ' ', firstname) ORDER BY lastname, firstname) names
  FROM tbl_Participants
  GROUP BY group_name
) t 

查看简化的demo

如果tbl_Groups 中有组而tbl_Participants 中没有行,并且您希望它们出现在结果中,则使用UNION ALL 比加入更容易。
添加到上述查询中:

UNION ALL
SELECT g.group_name, null, null, null
FROM tbl_Groups g
WHERE NOT EXISTS (
  SELECT 1 
  FROM tbl_Participants p
  WHERE p.group_name = g.group_name
)

【讨论】:

  • 我刚刚意识到这些查询以请求的格式列出了结果,按 group_name col 分组,但不适用于使用 ID 的 EDIT 函数。我会考虑一种不同的方法来按组添加/删除参与者。如果我想不出基于上述查询的方法,可能会按参与者级别进行编辑。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多