gpt4 book ai didi

mysql - 使用单个 MySQL 表的各种条件优化 SQL 查询以获得最大值

转载 作者:行者123 更新时间:2023-11-28 23:15:38 26 4
gpt4 key购买 nike

我有以下 SQL 查询

SELECT  *
FROM `sensor_data` AS `sd1`
WHERE (sd1.timestamp BETWEEN '2017-05-13 00:00:00'
AND '2017-05-14 00:00:00')
AND (`id` =
(
SELECT `id`
FROM `sensor_data` AS `sd2`
WHERE sd1.mid = sd2.mid
AND sd1.sid = sd2.sid
ORDER BY `value` DESC, `id` DESC
LIMIT 1)
)

背景:

我已经 checked the validity of the query通过将 LIMIT 1 更改为 LIMIT 0,查询工作没有任何问题。但是,对于 LIMIT 1,查询没有完成,它只是说明 loading,直到我关闭并重新启动。

分解查询:

我已将具有日期边界的查询分解如下:

SELECT  *
FROM `sensor_data` AS `sd1`
WHERE (sd1.timestamp BETWEEN '2017-05-13 00:00:00'
AND '2017-05-14 00:00:00')

这需要大约 0.24 秒来返回包含 8200 行的查询,每行有 5 列。

问题:

我怀疑我的查询的后半部分不正确或未优化。表格如下:

当前表:

+------+-------+-------+-----+-----------------------+
| id | mid | sid | v | timestamp |
+------+-------+-------+-----+-----------------------+
| 51 | 10 | 1 | 40 | 2015-05-13 11:56:01 |
| 52 | 10 | 2 | 39 | 2015-05-13 11:56:25 |
| 53 | 10 | 2 | 40 | 2015-05-13 11:56:42 |
| 54 | 10 | 2 | 40 | 2015-05-13 11:56:45 |
| 55 | 10 | 2 | 40 | 2015-05-13 11:57:01 |
| 56 | 11 | 1 | 50 | 2015-05-13 11:57:52 |
| 57 | 11 | 2 | 18 | 2015-05-13 11:58:41 |
| 58 | 11 | 2 | 19 | 2015-05-13 11:58:59 |
| 59 | 11 | 3 | 58 | 2015-05-13 11:59:01 |
| 60 | 11 | 3 | 65 | 2015-05-13 11:59:29 |
+------+-------+-------+-----+-----------------------+

问:如何为每个 mid 获取每个 sidMAX(v)NB#1: 在上面的例子中 ROW 53, 54, 55 具有相同的值 (40),但我想检索具有最新时间戳的行,即 ROW 55

预期输出:

+------+-------+-------+-----+-----------------------+
| id | mid | sid | v | timestamp |
+------+-------+-------+-----+-----------------------+
| 51 | 10 | 1 | 40 | 2015-05-13 11:56:01 |
| 55 | 10 | 2 | 40 | 2015-05-13 11:57:01 |
| 56 | 11 | 1 | 50 | 2015-05-13 11:57:52 |
| 58 | 11 | 2 | 19 | 2015-05-13 11:58:59 |
| 60 | 11 | 3 | 65 | 2015-05-13 11:59:29 |
+------+-------+-------+-----+-----------------------+

表的结构:

enter image description here

注意#2:由于此表有超过 1.1 亿个条目,因此设置日期界限非常重要,这限制了 24 小时内约 8000 个条目。

最佳答案

查询可以这样写:

SELECT t1.id, t1.mid, t1.sid, t1.v, t1.ts
FROM yourtable t1
INNER JOIN (
SELECT mid, sid, MAX(v) as v
FROM yourtable
WHERE ts BETWEEN '2015-05-13 00:00:00' AND '2015-05-14 00:00:00'
GROUP BY mid, sid
) t2
ON t1.mid = t2.mid
AND t1.sid = t2.sid
AND t1.v = t2.v
INNER JOIN (
SELECT mid, sid, v, MAX(ts) as ts
FROM yourtable
WHERE ts BETWEEN '2015-05-13 00:00:00' AND '2015-05-14 00:00:00'
GROUP BY mid, sid, v
) t3
ON t1.mid = t3.mid
AND t1.sid = t3.sid
AND t1.v = t3.v
AND t1.ts = t3.ts;

编辑和解释:

第一个子查询(第一个 INNER JOIN)根据 (mid, sid) 组合获取 MAX(v)。第二个子查询是为每个 (mid, sid, v) 识别 MAX(ts)。此时,两个查询不会影响彼此的结果。同样重要的是要注意 ts 日期范围选择是在两个子查询中独立完成的,因此最终查询要检查的行更少,并且没有额外的 WHERE 过滤器申请。

实际上,这转化为最初为每个 (mid, sid) 组合获取 MAX(v)(第一个子查询);如果对于给定的 (mid, sid) 组合,有多个具有相同值 MAX(v) 的记录,则通过选择MAX(ts) 对于第二个子查询获得的每个 (mid, sid, v) 组合。然后,我们通过两个 INNER JOIN 条件简单地将两个查询的输出相关联,以获取所需记录的 id

Demo

关于mysql - 使用单个 MySQL 表的各种条件优化 SQL 查询以获得最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43990650/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com