【问题标题】:MySQL - Using Order By result created by a subquery group_concat or join issueMySQL - 使用由子查询 group_concat 或连接问题创建的 Order By 结果
【发布时间】:2011-06-30 08:43:31
【问题描述】:

这是一个我已经困惑了很长时间的查询,我一直无法让它完全正确地工作,经过大约 40 小时的思考,我已经走到了这一步。

设置

对于示例问题,我们有 2 个表,其中一个是...

field_site_id             field_sitename           field_admins
1                         Some Site                1,
2                         Other Site               1,2,

另一个是管理员,比如......

field_user_id             field_firstname          field_lastname
1                         Joe                      Bloggs
2                         Barry                    Wills

现在所有这个查询的设计目的如下:

  • 列出数据库中的所有网站
  • 使用 JOIN 和 FIND_IN_SET 拉动每个管理员
    • 以及 GROUP_CONCAT(field_firstname, ' ', field_lastname) 和 GROUP BY 以使用真实用户名构建字段。
  • 还允许 HAVING 过滤自定义结果以进一步缩小结果范围。

这部分工作得很好。

我不知道如何实现的是按 GROUP_CONCAT 结果对结果进行排序,我想这是 ORDER BY 在 concat 函数之前工作,因此数据不存在按它排序,所以什么会是另一种选择吗?

代码示例:

SELECT *

GROUP_CONCAT(DISTINCT field_firstname, ' ', field_lastname ORDER BY field_lastname SEPARATOR ', ') AS field_admins_fullname,

FROM `table_sites`
LEFT JOIN `table_admins` ON FIND_IN_SET( `table_admins`.`field_user_id`, `table_sites`.`field_site_id` ) > 0
GROUP BY field_site_id

我还尝试了一个使用子查询来收集 group_concat 结果的查询,如下所示...

( SELECT GROUP_CONCAT(field_firstname, ' ', field_lastname ORDER BY field_lastname ASC SEPARATOR ', ') FROM table_admins 
WHERE FIND_IN_SET( `table_admins`.`field_user_id`, `table_sites`.`field_admins` ) > 0
) AS field_admins_fullname

结论

尝试 ORDER BY field_admins_fullname 的任何一种方式都不会创建正确的结果,它不会出错,但假设这是因为给定的 ORDER BY 是空白的,所以它只是做它想做的任何事情。

欢迎提出任何建议,如果这是不可能的,另一种推荐索引方法是什么?

【问题讨论】:

    标签: mysql sql-order-by subquery group-concat


    【解决方案1】:

    我认为您需要重复您在 ORDER BY 中选择的复杂 CONCAT 语句。

    所以你的 order by 会更像...

    ORDER BY (GROUP_CONCAT(DISTINCT field_firstname, ' ',
        field_lastname ORDER BY field_lastname SEPARATOR ', ')) ASC
    

    我还没有尝试过,但我遇到了类似的问题,这似乎可以解决,但如果没有 DISTINCT 等,它会简单得多。

    【讨论】:

      【解决方案2】:

      我看错了两件事:

      第一,是JOIN。它应该使用 s.field_admins 而不是 field_site_id

          ON FIND_IN_SET( a.field_user_id, s.field_admins ) > 0
      

      第二,您应该在GROUP_CONCAT() 中使用CONCAT() 函数(连接同一行中的字段)。

      试试这个:

      SELECT s.field_site_id
           , s.field_sitename
           , GROUP_CONCAT( CONCAT(a.field_firstname, ' ', a.field_lastname)
                           ORDER BY a.field_lastname ASC
                           SEPARATOR ', '
                         )
             AS field_admins_fullname
      FROM table_sites s
        LEFT JOIN table_admins a
          ON FIND_IN_SET( a.field_user_id, s.field_admins ) > 0
      GROUP BY s.field_site_id
      

      友情提示:

      Don't use         Do use
      ------------      --------
      table_sites       site
      table_admins      admin
      
      field_site_id     site_id 
      field_sitename    sitename
      field_admins      admins
      

      但真正应该强调的是您的设置。具有逗号分隔值的字段会导致这种可怕的查询,使用FIND_IN_SET() 进行连接,使用GROUP_CONCAT() 显示结果。很难看,难以维护,最重要的是,非常非常慢,因为没有索引可以使用。

      你应该有这样的东西:

      设置建议

      Table:  site
      
      site_id      sitename       
      1            Some Site      
      2            Other Site     
      
      
      Table:  site_admin
      
      site_id      admin_id      
      1            1
      2            1 
      2            2   
      
      
      Table:  admin
      
      user_id      firstname      lastname
      1            Joe            Bloggs
      2            Barry          Wills
      

      【讨论】:

        【解决方案3】:

        分组有误,试试这个?

        GROUP BY field_site_id
        

        【讨论】:

        • 虽然您认为 Group By 在错误的字段上是正确的,而且我还认为 Join 应该是 Left 的,但不幸的是,它并没有解决我遇到的真正问题能够按 field_admins_fullname ASC 排序。
        猜你喜欢
        • 1970-01-01
        • 2014-07-09
        • 1970-01-01
        • 1970-01-01
        • 2014-07-17
        • 2014-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多