GROUP_CONCAT 更改 GROUP BY 顺序

发布于 2024-10-26 04:03:21 字数 1152 浏览 5 评论 0原文

我有一个 VIEW(大量连接),输出按日期 ASC 排序的数据。按预期工作。

输出类似于:

ID date         tag1   other_data
1  25-03-2011   blue   fff   <=
1  26-03-2011   red    ggg
1  27-03-2011   pink   yyy
2  25-03-2011   red    yyy   <=
2  26-03-2011   orange rrr

如果我应用 GROUP BY ID。对于其他列,MySQL 输出每个 ID 的第一个找到的行。我在文档中的某个地方读到了这个。

SELECT * FROM `myVIEW`  
GROUP BY `ID`  
  ID date         tag1  other_data  
  1  25-03-2011   blue   fff   <=
  2  25-03-2011   red    yyy   <=

现在让我们添加一个 GROUP_CONCAT(tags1)

SELECT *,CONCAT_GROUP(`tag1`) AS `tags`  
FROM `myVIEW`  
GROUP BY `ID`

因为我应用了 CONCAT_GROUP,结果变得很奇怪。我期待:

ID date         tag1   other_data   tags
1  25-03-2011   blue   fff          blue,red,pink
2  25-03-2011   red    yyy          red,orange

查询正在返回,例如:

ID date         tag1   other_data   tags
1  26-03-2011   red    ggg          blue,red,pink
2  25-03-2011   red    yyy          red,orange

看起来 GROUP_CONCAT 不再保留 VIEW 顺序。这是正常的吗?

I have a VIEW (lots of joins) that outputs data ordered by a date ASC. Works as expected.

OUTPUT similar to:

ID date         tag1   other_data
1  25-03-2011   blue   fff   <=
1  26-03-2011   red    ggg
1  27-03-2011   pink   yyy
2  25-03-2011   red    yyy   <=
2  26-03-2011   orange rrr

If I apply a GROUP BY ID. For the other columns MySQL outputs the first found row of each ID. I read this somewhere in te docs.

SELECT * FROM `myVIEW`  
GROUP BY `ID`  
  ID date         tag1  other_data  
  1  25-03-2011   blue   fff   <=
  2  25-03-2011   red    yyy   <=

Now lets add a GROUP_CONCAT(tags1)

SELECT *,CONCAT_GROUP(`tag1`) AS `tags`  
FROM `myVIEW`  
GROUP BY `ID`

Since I apply the CONCAT_GROUP the results get odd. I was expecting:

ID date         tag1   other_data   tags
1  25-03-2011   blue   fff          blue,red,pink
2  25-03-2011   red    yyy          red,orange

The query is returning, for example:

ID date         tag1   other_data   tags
1  26-03-2011   red    ggg          blue,red,pink
2  25-03-2011   red    yyy          red,orange

Looks like GROUP_CONCAT no longer preserves the VIEW order. Is this normal?

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

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

发布评论

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

评论(3

梦毁影碎の 2024-11-02 04:03:32

这是因为 mysql 不保证对于聚合函数中未使用或未用于分组依据的字段将返回哪些确切行。

需要明确的是,“成熟”的 RDBMS(例如 postgre、sql server、oracle)不允许在 GROUP BY 中指定 *(或任何没有聚合的字段或未在 GROUP 中指定的字段) BY) - 这是很大的“限制”。

That is because mysql does not guarantee what exact rows will be returned for the fields that are not used in aggregation functions or wasn't used to group by.

And to be clear "mature" rdbms (such as postgre, sql server, oracle) do not allow to specify * in GROUP BY (or any fields without aggregation or that was not specified in GROUP BY) - and it is great "limitation".

淑女气质 2024-11-02 04:03:30

订购 GROUP_CONCAT 怎么样?

SELECT value1, GROUP_CONCAT(value1 ORDER BY date DESC)   
FROM table1  
GROUP BY value1;

这就是您需要假设的语法。

How about ordering your GROUP_CONCAT?

SELECT value1, GROUP_CONCAT(value1 ORDER BY date DESC)   
FROM table1  
GROUP BY value1;

That's the syntax you need a presume.

泼猴你往哪里跑 2024-11-02 04:03:26

看起来GROUP_CONCAT不再保留VIEW顺序。这正常吗?

是的,这很正常。

您永远不应该依赖未分组和未聚合字段的返回顺序。

GROUP_CONCAT 有自己的 ORDER BY 子句,优化器会考虑该子句,并可以更改解析记录的顺序。

要返回第一条记录以及 GROUP_CONCAT,请使用以下命令:

SELECT  m.*, gc
FROM    (
        SELECT  id, MIN(date) AS mindate, GROUP_CONCAT(tags) AS gc
        FROM    myview
        GROUP BY
                id
        ) md
JOIN    m.*
ON      m.id = md.id
        AND m.date = md.mindate

Looks like GROUP_CONCAT no longer preserves the VIEW order. Is this normal?

Yes, it is normal.

You should not rely, ever, on the order in which ungrouped and unaggregated fields are returned.

GROUP_CONCAT has its own ORDER BY clause which the optimizer takes into account and can change the order in which is parses the records.

To return the first record along with GROUP_CONCAT, use this:

SELECT  m.*, gc
FROM    (
        SELECT  id, MIN(date) AS mindate, GROUP_CONCAT(tags) AS gc
        FROM    myview
        GROUP BY
                id
        ) md
JOIN    m.*
ON      m.id = md.id
        AND m.date = md.mindate
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文