【问题标题】:MySQL ORDER BY ignored with GROUP BY (Efficient work around?)MySQL ORDER BY 被 GROUP BY 忽略(有效的解决方法?)
【发布时间】:2011-02-24 20:02:17
【问题描述】:

我觉得有一个简单的解决方案——我查看了有关 Stack Overflow 的其他问题,但它们似乎效率低下,或者我做错了。

这是我正在使用的表格的简化版本。

CREATE TABLE object_values (
  object_value_id INT PRIMARY KEY,
  object_id INT,
  value FLOAT,
  date_time DATETIME,
  INDEX (object_id)
);

CREATE TABLE object_relations (
  object_group_id INT,
  object_id INT,
  INDEX (object_group_id, object_id)
);

存在多对一关系——每个对象有多个对象值(每个对象平均有 150 个对象值)

我想根据 object_group_id 获取每个 object_id 的最后一个对象值(由 date_time 字段确定)。

当前查询:

SELECT a.`object_id`, a.`value` 
FROM `object_values` AS a 
    LEFT JOIN `object_relations` AS b 
        ON ( a.`object_id` = b.`object_id` ) 
WHERE b.`object_group_id` = 105 
ORDER BY a.`date_time` DESC

这会拉回所有记录——如果我执行 GROUP BY a.object_id 那么 ORDER BY 会被忽略

我尝试了一系列变体——我很抱歉,因为我知道这是一个常见问题,但尝试其他解决方案到目前为止还没有完全奏效。任何帮助将不胜感激。

一些解决方案在大约 70 秒后返回结果 - 这是一个大型系统,因此需要更快一些。

【问题讨论】:

  • 我怀疑 order by 被忽略了; GROUP BY 可能不会返回您想要的记录,但最终行将被排序。您没有退回您订购的商品,那么如何验证这一点?我猜想整个查询格式不正确并返回错误/丢失的行。

标签: mysql many-to-one


【解决方案1】:
SELECT a.object_id, a.`value`
FROM object_values a JOIN object_relations b
    ON a.object_id = b.object_id
    JOIN (
    SELECT a.object_id, MAX(a.date_time) MaxTime
    FROM object_relations b JOIN object_values a
        ON a.object_id = b.object_id
    WHERE b.`object_group_id` = 105 
    GROUP BY a.object_id
  ) g ON a.object_id = g.object_id AND a.date_time = g.MaxTime
WHERE b.`object_group_id` = 105 
GROUP BY a.object_id

如果在单个组中永远不会有重复的date_time,您可以省略最后的GROUP BY

【讨论】:

  • 我对您的解决方案很感兴趣——必须稍微修改一下(将 ON 子句中的“g.date_time”更改为“g.MaxTime”),它撤回了 46 条记录,应该只拉回 10。
  • @kerry 抱歉,我以为你是按object_group_id 分组的。查看更新的答案
  • @Scrum -- 完美,非常快
【解决方案2】:

试试这个不带分组依据的版本,使用子查询来拉取每个对象的最大日期:

SELECT a.`object_id`, a.`value` 
FROM `object_relations` b 
JOIN `object_values` a 
 ON b.`object_id` = a.`object_id`
 AND b.`object_group_id` = 105
WHERE a.`date_time` = (select MAX(date_time) from object_values where object_id = a.object_id)

由于您在 where 子句中指定了组 ID,因此不需要左连接,因此我将组设置为连接中的主表。这可以通过多种方式完成。如果 WHERE 只是更改为 AND,子查询也可以移动到 join 子句。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    相关资源
    最近更新 更多