迭代SQL中的数据[关闭]
Posted
技术标签:
【中文标题】迭代SQL中的数据[关闭]【英文标题】:Iterate over data in SQL [closed] 【发布时间】:2020-08-31 13:17:24 【问题描述】:拥有此数据集:https://www.db-fiddle.com/f/6vmgx4krsgMRgprDjErdqu/0
我想要一个额外的列来显示与之前条目的时间距离,我该如何实现?
提前非常感谢你:)
【问题讨论】:
您的服务器上精确的 mysql 版本是多少? 之前输入是什么意思 - 是客户输入的吗? 【参考方案1】:正如您在小提琴中所说,您使用 MySQL 5,7
您必须使用用户定义的变量。
我选择了 TIMEDIFF 来显示差异,因为你没有说明你需要哪些信息,所以我选择了这个,但是由于你有两个值,你可以使用不同的 mysql 函数
架构 (MySQL v5.7)
CREATE TABLE `someTable` (
`ID` INT,
`POS` INT,
`Date` DATETIME,
`Customer` VARCHAR(64)
);
INSERT INTO `someTable` VALUES
(1, 10, "2017-03-10 08:00:00", "Peter"),
(2, 11, "2017-03-10 08:00:01", "Peter"),
(3, 12, "2017-03-10 08:00:04", "Peter"),
(4, 17, "2017-03-10 08:00:05", "Peter"),
(5, 16, "2017-03-10 08:00:08", "Karl"),
(6, 17, "2017-03-10 08:00:09", "Karl"),
(7, 10, "2017-03-10 08:00:12", "Peter"),
(8, 10, "2017-03-10 08:00:13", "Peter");
SELECT * FROM someTable
查询 #1
SELECT
ID,
POS
,`Customer`
,IF(@date = `Date`,0,TIMEDIFF(`Date`, @date)) diff
,@date := `Date` 'Date'
FROM someTable, (SELECT @date := (SELECT MIN(`Date`) FROM someTable)) A;
| ID | POS | Customer | diff | Date |
| --- | --- | -------- | --------------- | ------------------- |
| 1 | 10 | Peter | 0 | 2017-03-10 08:00:00 |
| 2 | 11 | Peter | 00:00:01.000000 | 2017-03-10 08:00:01 |
| 3 | 12 | Peter | 00:00:03.000000 | 2017-03-10 08:00:04 |
| 4 | 17 | Peter | 00:00:01.000000 | 2017-03-10 08:00:05 |
| 5 | 16 | Karl | 00:00:03.000000 | 2017-03-10 08:00:08 |
| 6 | 17 | Karl | 00:00:01.000000 | 2017-03-10 08:00:09 |
| 7 | 10 | Peter | 00:00:03.000000 | 2017-03-10 08:00:12 |
| 8 | 10 | Peter | 00:00:01.000000 | 2017-03-10 08:00:13 |
View on DB Fiddle
【讨论】:
【参考方案2】:如果您运行的是 MySQL 8.0,只需使用 lag()
和 timetstampdiff()
。假设您想要与同一customer
的“先前”记录的日期差异,并且它应该以秒表示:
select
t.*,
timestampdiff(
second,
lag(date, 1, date) over(partition by customer order by date),
date
) diff_seconds
from sometable t
这为每组的第一条记录提供了0
秒的差异。
如果您运行的是早期版本,那么我建议您使用相关子查询。虽然它的效率可能比用户变量低一点,但它更安全,而且面向未来(计划在未来版本的 MySQL 中删除用户变量):
select
t.*,
timestampdiff(
second,
coalesce((select max(t1.date) from sometable t1 where t1.customer = t.customer and t1.date < t.date), date),
date
) diff_seconds
from sometable t
对于您的示例数据,both queries return:
| ID | POS | Date | Customer | diff_seconds |
| --- | --- | ------------------- | -------- | ------------ |
| 1 | 10 | 2017-03-10 08:00:00 | Peter | 0 |
| 2 | 11 | 2017-03-10 08:00:01 | Peter | 1 |
| 3 | 12 | 2017-03-10 08:00:04 | Peter | 3 |
| 4 | 17 | 2017-03-10 08:00:05 | Peter | 1 |
| 5 | 16 | 2017-03-10 08:00:08 | Karl | 0 |
| 6 | 17 | 2017-03-10 08:00:09 | Karl | 1 |
| 7 | 10 | 2017-03-10 08:00:12 | Peter | 7 |
| 8 | 10 | 2017-03-10 08:00:13 | Peter | 1 |
【讨论】:
【参考方案3】:像这样的东西不能解决问题:
insert into @temp ([ID], [Date])
select
t.[ID],
datediff(day, Lag(t.[Date]) over(order by t.[Date]), t.[Date]) as [DateDiffFromPrevRow]
from someTable t
select
t.[ID],
t.[POS],
t.[Date],
t.[Customer],
temp.[DateDiffFromPrevRow]
from sometable t
join @temp temp on temp.[ID] = t.[ID]
【讨论】:
问题是 [mysql]-tagged,而不是 [sql-server]。 在 MySQL 8.0 版本中还引入了 MySQL windows 函数。 dbfiddle 链接使用的是 MySQL 5.7,因此他甚至无法使用 LAG 我的错,错过了看到 mysql 标签以上是关于迭代SQL中的数据[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
如何仅使用 C++ 中的迭代器正确迭代 3D 向量? [关闭]