遍历 SQL 中的数据

Iterate over data in SQL

拥有此数据集:https://www.db-fiddle.com/f/6vmgx4krsgMRgprDjErdqu/0

我想有一个额外的列显示到之前条目的时间距离,我该如何实现?

非常感谢您:)

像这样的东西就可以了:

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]

正如您在 fiddle 中所述,您使用 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

如果您是运行 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 秒。

如果你是运行更早的版本,那么我会推荐相关子查询。虽然它可能比用户变量效率低一点,但它更安全,并且future-proof(用户变量计划在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            |