此查询的替代方案,可在MariaDb 10.1下运行

时间:2018-10-31 11:19:11

标签: sql mariadb window-functions

此查询在Mysql 8下可以正常工作,但是我的服务器上使用了MariaDB 10.1。您知道是否有替代方法吗?以及如何实现呢?

SELECT * FROM (
SELECT
  *,
  SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(hs.`ending_hour`, hs.`starting_hour`))) OVER (ORDER BY hs.starting_hour RANGE BETWEEN INTERVAL '12' HOUR PRECEDING AND INTERVAL '12' HOUR following)) AS tot
FROM
  time_table hs
  WHERE hs.`starting_hour` > DATE_SUB(NOW(), INTERVAL 50 DAY) AND hs.`ending_hour` <= NOW()
 ORDER BY hs.`starting_hour` ASC
 ) t1
  HAVING tot >= '14:00:00' 
 ;

fiddle

问题是RANGE BETWEEN INTERVAL上的OVER窗口功能目前在MariaDB下不存在。

谢谢

样本数据:

        id  starting_hour        ending_hour          
------  -------------------  ---------------------
     1  2018-09-02 06:00:00  2018-09-02 08:30:00  
     2  2018-09-02 08:30:00  2018-09-02 10:00:00  
     4  2018-09-03 11:00:00  2018-09-03 15:00:00  
     5  2018-09-04 15:30:00  2018-09-04 16:00:00  
     6  2018-09-04 16:15:00  2018-09-04 17:00:00  
     7  2018-09-19 00:00:00  2018-09-19 03:00:00  
     8  2018-09-19 04:00:00  2018-09-19 15:00:00  
     9  2018-09-20 00:00:00  2018-09-20 22:01:00  
    10  2018-10-21 12:00:00  2018-10-21 11:00:00  
    11  2018-10-29 09:09:00  2018-10-29 10:10:00  
    12  2018-10-09 02:10:00  2018-10-09 14:00:00  

在我的用例ID 7、8和9中就是结果。

重新编辑

感谢@Gordon Linoff的答案,这是已更正的查询。 但是最终无法按预期工作。增加INTERVAL 50 DAY会返回MySQL窗口功能不会返回的不需要的行。

SELECT hs.*,
       (
       SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(hs2.ending_hour, hs2.starting_hour))))
        FROM hours_sailor hs2
        WHERE hs2.starting_hour >= DATE_SUB(hs.starting_hour, INTERVAL 12 HOUR) AND hs2.starting_hour <= DATE_SUB(NOW(), INTERVAL 12 HOUR)
      ) AS duration
FROM `time_table` hs
WHERE hs.`starting_hour` > DATE_SUB(NOW(), INTERVAL 50 DAY) AND hs.`ending_hour` <= NOW()
HAVING duration >= '14:00:00' 
ORDER BY hs.starting_hour ASC;

1 个答案:

答案 0 :(得分:0)

您可以使用相关子查询来表达这一点。我认为这是等效的逻辑:

SELECT hs.*,
       (SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(hs2.ending_hour, hs2.starting_hour)))
        FROM time_table hs2
        WHERE hs2.starting_hour >= hs.starting_hour - INTERVAL '12' HOUR AND
              hs2.starting_hour <= hs.starting_hour + INTERVAL '12' HOUR
      ) AS tot
FROM time_table hs
WHERE hs.starting_hour > DATE_SUB(NOW(), INTERVAL 50 DAY) AND
      hs.ending_hour <= NOW()
HAVING tot >= '14:00:00' 
ORDER BY hs.starting_hour ASC;

编辑:

如果您还希望计算“范围”的时间限制,则需要将其包括在子查询中。该过滤功能内置于窗口功能中,但通常比功能障碍:

SELECT hs.*,
       (SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(hs2.ending_hour, hs2.starting_hour)))
        FROM time_table hs2
        WHERE hs2.starting_hour >= hs.starting_hour - INTERVAL '12' HOUR AND
              hs2.starting_hour <= hs.starting_hour + INTERVAL '12' HOUR AND
              hs2.starting_hour > DATE_SUB(NOW(), INTERVAL 50 DAY) AND
              hs2.ending_hour <= NOW()
      ) AS tot
FROM time_table hs
WHERE hs.starting_hour > DATE_SUB(NOW(), INTERVAL 50 DAY) AND
      hs.ending_hour <= NOW()
HAVING tot >= '14:00:00' 
ORDER BY hs.starting_hour ASC;