0

这是我困惑了很长时间的一个问题,我一直无法让它正常工作,经过大约 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 是空白的,所以它只是做它想做的任何事情。

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

4

3 回答 3

3

Two things I see wrong:

1st, is the JOIN. It should be using s.field_admins and not field_site_id :

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

2nd, you should use the CONCAT() function (to conactenate fields from the same row) inside the GROUP_CONCAT().

Try this:

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

Friendly advice:

Don't use         Do use
------------      --------
table_sites       site
table_admins      admin

field_site_id     site_id 
field_sitename    sitename
field_admins      admins

But what should really be stressed, is your setup. Having fields that have comma separated values lead to this kind of horrible queries that use FIND_IN_SET() for joins and GROUP_CONCAT() for showing results. Horrible to see, difficult to maintain and most important, very, very slow as no index can be used.

You should have something like this instead:

Setup suggestion

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
于 2011-06-11T22:56:22.027 回答
1

我认为您需要重复CONCAT您在ORDER BY.

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

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

我还没有尝试过,但我有一个类似的问题,这似乎解决了,但没有DISTINCTetc就简单多了。

于 2011-06-11T22:22:54.620 回答
0

组错了,试试这个?

GROUP BY field_site_id
于 2011-02-19T13:33:08.637 回答