首页 > 解决方案 > 使用 Group By 执行 Limit by 和 Max 在多表连接中的 Order by 和 Limit

问题描述

Select group_concat(ID SEPARATOR '|') 
  from TableJ J
  Left Join TableL L on L.J_ID=J.ID
  Left Join TableB B on B.LJ_ID=L.F_ID
  Left Join TableLJ LJ on LJ.ID=L.F_ID
Group 
    by J.ID

输出返回记录,如

ETC

问题是我需要将结果中的记录/管道数限制为 5 条记录。

在 TableLJ 中有一个字段Population,我可以使用它来排序和限制,但没有多少摆弄可以让我指定我想从该表 PER 组中选择前 5 个。

更新是我可以执行以下操作来限制 group_concat (仍然不能解决让它们首先按 LJ.Population 排序)

substring_index(group_concat(ID SEPARATOR '|'),'|',5)

标签: mysqljoingroup-bylimit

解决方案


  • Group_Concat()函数有一个可选Order By子句,使用它我们可以根据另一个/相同的列对列值进行排序。
  • 您可以使用Substring_Index()函数将连接的字符串限制为每组 5 个。

尝试:

SELECT Substring_Index(Group_concat(ID 
                                    ORDER BY LJ.Population ASC 
                                    SEPARATOR '|'), 
                       '|', 
                       5) 
FROM   TableJ AS J
       LEFT JOIN TableL AS L
              ON L.J_ID = J.ID
       LEFT JOIN TableB AS B
              ON B.LJ_ID = L.F_ID
       LEFT JOIN TableLJ AS LJ
              ON LJ.ID = L.F_ID
GROUP  BY J.ID 

MySQL 8.0.2 及更高版本中,我们可以利用Window Functions来确定Row_Number()分区内的J.ID. 我们可以通过排序LJ.Population得到相应的行号。

现在,将此结果集用作派生表,并仅考虑行号为 5 的行。然后您可以Group By相应地执行此操作Group_Concat()

SELECT   Group_Concat(dt.ID ORDER BY dt.rownumber ASC SEPARATOR '|')
FROM     (
          SELECT    J.ID,
                    ROW_NUMBER() OVER (PARTITION BY J.ID
                                       ORDER BY LJ.Population ASC) AS rownumber
          FROM      TableJ   AS J
          LEFT JOIN TableL   AS L
            ON  L.J_ID = J.ID
          LEFT JOIN TableB   AS B
            ON  B.LJ_ID = L.F_ID
          LEFT JOIN TableLJ  AS LJ
            ON  LJ.ID = L.F_ID ) AS dt
WHERE    dt.rownumber <= 5
GROUP BY dt.ID 

推荐阅读