MySQL - 使用Order By由子查询group_concat或join问题创建的结果

时间:2011-02-19 12:32:59

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

这是一个我一直困惑的问题很长一段时间,我从来没有能够让它正常工作,经过大约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是空的,所以它只是做它想要的任何事情。

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

3 个答案:

答案 0 :(得分:3)

我看错了两件事:

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

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

第二,你应该使用CONCAT()内的GROUP_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

答案 1 :(得分:1)

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

所以你的订单会更像......

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

我没有试过这个,但是我有一个类似的问题,这似乎解决了,但没有DISTINCT等就更简单了。

答案 2 :(得分:0)

错误的群体,试试这个?

GROUP BY field_site_id