获取最低Time对应的DateTime

Posted

技术标签:

【中文标题】获取最低Time对应的DateTime【英文标题】:Get DateTime corresponding to the lowest Time 【发布时间】:2020-03-11 11:26:55 【问题描述】:

我想获取对应于最低和最大时间的日期和 ID,分别是下表中 ID 为 5 和 4 的极端行。

请注意以下几点:

日期以毫秒为单位存储 ID 反映了Order By Date ASC 下面我已经分时间说明清楚了 * 表示要返回的两行。 值应作为列返回,即:SELECT minID, minDate, maxID, maxDate FROM myTable
| ID | Date                | TimeOnly  |
|----|---------------------|-----------|
| 5  | 14/11/2019 10:01:29 | 10:01:29* |
| 10 | 15/11/2019 10:01:29 | 10:01:29  |
| 6  | 14/11/2019 10:03:41 | 10:03:41  |
| 7  | 14/11/2019 10:07:09 | 10:07:09  |
| 11 | 15/11/2019 12:01:43 | 12:01:43  |
| 8  | 14/11/2019 14:37:16 | 14:37:16  |
| 1  | 12/11/2019 15:04:50 | 15:04:50  |
| 9  | 14/11/2019 15:04:50 | 15:04:50  |
| 2  | 13/11/2019 18:10:41 | 18:10:41  |
| 3  | 13/11/2019 18:10:56 | 18:10:56  |
| 4  | 13/11/2019 18:11:03 | 18:11:03* |

【问题讨论】:

见:Why should I provide an MCRE for what seems to me to be a very simple SQL query? 【参考方案1】:

在早期版本的 mysql 中,您可以使用几个内联查询。这是一个直接的选项,在这里可能非常有效:

select 
    (select ID from mytable order by TimeOnlylimit 1) minID,
    (select Date from mytable order by TimeOnly limit 1) minDate,
    (select ID from mytable order by TimeOnly desc limit 1) maxID,
    (select Date from mytable order by TimeOnly desc limit 1) maxDate

【讨论】:

【参考方案2】:

MySQL 8+ 的一个选项,使用带有旋转逻辑的 ROW_NUMBER

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (ORDER BY TimeOnly) rn_min,
        ROW_NUMBER() OVER (ORDER BY Date TimeOnly) rn_max
    FROM yourTable
)

SELECT
    MAX(CASE WHEN rn_min = 1 THEN ID END) AS minID,
    MAX(CASE WHEN rn_min = 1 THEN Date END) AS minDate
    MAX(CASE WHEN rn_max = 1 THEN ID END) AS maxID,
    MAX(CASE WHEN rn_max = 1 THEN Date END) AS maxDate
FROM cte;

这是 MySQL 5.7 或更早版本的一个选项:

SELECT
    MAX(CASE WHEN pos = 1 THEN ID END) AS minID,
    MAX(CASE WHEN pos = 1 THEN Date END) AS minDate
    MAX(CASE WHEN pos = 2 THEN ID END) AS maxID,
    MAX(CASE WHEN pos = 2 THEN Date END) AS maxDate
FROM
(
    SELECT ID, Date, 1 AS pos FROM yourTable
    WHERE TimeOnly = (SELECT MIN(TimeOnly) FROM yourTable)
    UNION ALL
    SELECT ID, Date, 2 FROM yourTable
    WHERE TimeOnly = (SELECT MAX(TimeOnly) FROM yourTable)
) t;

第二个 5.7 选项使用类似的旋转逻辑,但不是 ROW_NUMBER 而是使用子查询来识别最小和最大记录。这些记录使用联合以及用于跟踪哪个记录是最小/最大的标识符一起组合在一起。

【讨论】:

感谢您的快速答复。可悲的是,我不是第 8 版,但仍然是 7.x: @Enissay 我更新了 MySQL 早期版本的选项。 不应该是WHERE TimeOnly = (SELECT MIN(TimeOnly) FROM yourTable)吗? “感谢您的快速回答。遗憾的是我不在第 8 版,但仍然是 7.x” 嗯 @Enissay MySQL 7.x 存在吗? MySQL 从 MySQL 5.7 直接升级到 MySQL 8,我猜他们发现 MySQL 8 非常好,他们跳过了一些主要版本号。 @RaymondNijland 哈哈,我后来注意到了我的错误,但忽略了它,因为它无论如何都可以推断出来......我的意思确实是 5.7 ;-)【参考方案3】:

你可以这样做:

SELECT minval.ID, minval.Date, maxval.ID, maxval.Date
FROM (
    SELECT ID, Date
    FROM t
    ORDER BY CAST(Date AS TIME)
    LIMIT 1
) AS minval
CROSS JOIN (
    SELECT ID, Date
    FROM t
    ORDER BY CAST(Date AS TIME) DESC
    LIMIT 1
) AS maxval

如果您想要两行,请将 CROSS JOIN 查询更改为 UNION ALL 查询。

Demo on db<>fiddle

【讨论】:

以上是关于获取最低Time对应的DateTime的主要内容,如果未能解决你的问题,请参考以下文章

python实现的最低松弛度优先(LLF)算法

使用python获取当前的时间

使用python获取当前的时间

Python-时间模块-time

查找最小值并包含正确的列值

算法树中两个结点的最低公共祖结点