【问题标题】:MariaDB MAX sort failingMariaDB MAX 排序失败
【发布时间】:2021-01-14 17:49:36
【问题描述】:

编辑:我已经修改了问题和示例,因为上一个示例仅包含一个城市。

我正在寻找每个城市一行,其中 max_wind 或 max_gust 值最高。

这是一个基本查询 (http://sqlfiddle.com/#!9/42f63e/2):

        SELECT *
          FROM high_wind 
         WHERE timestamp > NOW() - INTERVAL 72 HOUR;                                                                              
+------+-----------+----------+----------+---------------------+
| hid  | city      | max_wind | max_gust | timestamp           |
+------+-----------+----------+----------+---------------------+
| 4784 | Vancouver | 63       | 90       | 2021-01-13 08:26:00 |
| 4785 | Vancouver | 54       | 71       | 2021-01-13 08:40:00 |
| 4786 | Calgary   | 52       | 71       | 2021-01-13 15:35:00 |
| 4787 | Calgary   | 57       | 79       | 2021-01-13 17:53:00 |
| 4788 | Calgary   | 67       | 86       | 2021-01-13 18:14:00 |
| 4789 | Calgary   | 70       | 84       | 2021-01-13 18:40:00 |
| 4790 | Calgary   | 51       | 86       | 2021-01-13 19:00:00 |
| 4791 | Calgary   | 55       | 75       | 2021-01-13 20:00:00 |
| 4792 | Saskatoon | 66       | 81       | 2021-01-14 00:18:00 |
| 4793 | Saskatoon | 53       | 73       | 2021-01-14 01:26:00 |
| 4794 | Saskatoon | 59       | 77       | 2021-01-14 01:44:00 |
| 4795 | Saskatoon | 72       | 91       | 2021-01-14 02:00:00 |
| 4796 | Saskatoon | 77       | 103      | 2021-01-14 03:00:00 |
| 4797 | Saskatoon | 52       | 65       | 2021-01-14 05:00:00 |
| 4798 | Saskatoon | 57       | 68       | 2021-01-14 06:13:00 |
| 4799 | Saskatoon | 50       | 64       | 2021-01-14 09:00:00 |
| 4800 | Saskatoon | 51       | 61       | 2021-01-14 15:00:00 |
| 4801 | Resolute  | 51       |          | 2021-01-15 04:00:00 |
+------+-----------+----------+----------+---------------------+
18 rows in set (0.004 sec)

根据上述数据样本,这将是最终的预期结果:

+------+-----------+----------+----------+---------------------+
| hid  | city      | max_wind | max_gust | timestamp           |
+------+-----------+----------+----------+---------------------+
| 4784 | Vancouver | 63       | 90       | 2021-01-13 08:26:00 |
| 4788 | Calgary   | 67       | 86       | 2021-01-13 18:14:00 |
| 4796 | Saskatoon | 77       | 103      | 2021-01-14 03:00:00 |
| 4801 | Resolute  | 51       |          | 2021-01-15 04:00:00 |
+------+-----------+----------+----------+---------------------+

我以为我找到了使用以下 INNER JOIN 查询的解决方案,但结果好坏参半。在这里它正确地产生了两个结果,但错过了另外两个。

        SELECT *
          FROM high_wind a 
          JOIN 
             ( SELECT city
                    , MAX(max_wind) max_wind
                   , MAX(max_gust) max_gust 
              FROM high_wind
             WHERE timestamp >= NOW() - INTERVAL 72 HOUR 
             GROUP 
                BY city
             ) b 
            ON a.city = b.city 
           AND a.max_wind = b.max_wind 
           AND a.max_gust = b.max_gust 
         WHERE timestamp >= NOW() - INTERVAL 72 HOUR;          
                    
+------+-----------+----------+----------+---------------------+
| hid  | city      | max_wind | max_gust | timestamp           |
+------+-----------+----------+----------+---------------------+
| 4784 | Vancouver | 63       | 90       | 2021-01-13 08:26:00 |
| 4801 | Resolute  | 51       |          | 2021-01-15 04:00:00 |
+------+-----------+----------+----------+---------------------+
2 rows in set (0.006 sec)

【问题讨论】:

  • 说风速最高的城市/日期时间与阵风最大的城市/日期时间相同是不正确的。您需要识别两者,然后使用 distinct 如果碰巧是同一个城市/日期时间

标签: mysql mariadb max


【解决方案1】:
SELECT hw.*
    FROM (
        SELECT MAX(wind) AS max_wind,
               MAX(gust) AS max_gust
            FROM high_wind
            WHERE ...
         ) AS mx
    JOIN high_wind AS hw  ON (   hw.wind = mx.max_wind
                              OR hw.gust = mx.max_gust )
    WHERE ...
    ORDER BY ...

如果最大值是针对同一城市和时间的,您可能会得到 1 行。

如果不同城市或时间的 MAX(..) 值相同,则可能超过 2 行。

如果您在 high_wind 中有一百万行,我们可以讨论索引以帮助提高性能。除非您添加 INDEX(wind)INDEX(gust),否则我的查询将需要 2 次全表扫描。但如果您需要WHERE 中的某些内容(例如省份限制或日期范围),这些索引就不够用了。

对于简单的WHERE timestamp > ...,添加

INDEX(timestamp)
INDEX(wind, timestamp)
INDEX(gust, timestamp)

更多

不要VARCHAR 用于数字(或日期)值:

`max_wind` varchar(20) DEFAULT NULL,

这样,“102”小于“99”!

【讨论】:

  • 感谢您的示例!目的是每隔 X 小时运行一次此查询,范围为前 X 小时(即 NOW() - INTERVAL 8 HOUR)。
  • @skyblaster - 如果每小时有“很多”条目,那么我会推动您构建和维护一个“汇总表”。但是每 8(或 12 或 13)小时的读数似乎很少?
  • 这是正确的。 “每小时”监测的城镇/城市不到 50 个,只有超过 50 公里/小时的风速记录在此表中。
  • @skyblaster - 那么,可能有几个小时,甚至几天,表格中没有行?这可能会导致额外的代码来识别这种情况并提供NULL 或其他任何东西。
  • 我重新设计了这个问题,感觉我越来越接近了。请看sqlfiddle.com/#!9/42f63e/15
猜你喜欢
  • 1970-01-01
  • 2021-09-27
  • 1970-01-01
  • 2014-07-07
  • 1970-01-01
  • 2021-05-17
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多