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

发布于 2024-10-17 22:50:24 字数 1745 浏览 8 评论 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 是空白的,所以它只是做它想做的事情。

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

This is a query I've been puzzling over for quite some time, I've never been able to get it to work quite right and after about 40 hours of pondering I've gotten to this point.

Setup

For the example issue we have 2 tables, one being...

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

And the other is admins like...

field_user_id             field_firstname          field_lastname
1                         Joe                      Bloggs
2                         Barry                    Wills

Now all this query is designed to do is the following:

  • List all sites in the database
  • Using a JOIN and FIND_IN_SET to pull each admin
    • And GROUP_CONCAT(field_firstname, ' ', field_lastname) with a GROUP BY to build a field with the real user names.
  • Also allow HAVING to filter on the custom result to narrow the results down further.

All this part works perfectly fine.

What I can't work out how to achieve is to sort the results by the GROUP_CONCAT result, I imagine this is being the ORDER BY works before the concat function therefore the data doesn't exist to order by it, so what would the alternative be?

Code examples:

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

I also tried a query that used a subquery to gather the group_concat result as below...

( 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

Conclusion

Either way attempting to ORDER BY field_admins_fullname will not create the correct results, it won't error out but assume that's because the given ORDER BY is blank so it just does whatever it wants.

Any suggestions would be welcome, if this is just not possible, what would be another recommend index methodology?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

撩人痒 2024-10-24 22:50:24

我认为有两件事是错误的:

第一,是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

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
八巷 2024-10-24 22:50:24

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

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

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

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

I think you need to repeat the complex CONCAT statement you are selecting within the ORDER BY.

So your order by would be more like...

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

I have not tried this but I had a similar issue which this seemed to solve but it was much simpler without the DISTINCT etc.

↙厌世 2024-10-24 22:50:24

分组依据错误,试试这个?

GROUP BY field_site_id

wrong group by, try this ?

GROUP BY field_site_id
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文