天数差异基于从后续行中选择的日期

Days diff based on selected date from succeeding row

我想根据 date_created 计算后续行的天数差异,如何从查询中获取后续或先前的数据行结果?

SELECT 
    -- *,
    h.date_created,
    -- (select date_created where id = h.id and pci_s = h.pci_s + 1) as dc,
    h.id,
    h.date_created,
    CONCAT('B', h.pci_b) AS batch,
    h.pci_s,
    DATEDIFF(h.date_created, h.date_created) as days_in_stage
FROM
    historical h
WHERE
    h.pci_b = 1
;

预计

date_created    id  date_created    batch   pci_s   days_in_stage
2021-07-18T06:32:26Z    1   2021-07-18T06:32:26Z    B1  0   0
2021-07-20T06:32:26Z    4   2021-07-20T06:32:26Z    B1  1   2 

这是 jsfiddle

http://sqlfiddle.com/#!9/f32a242/3

当前使用:Mysql 5.7.33

有了 MySQL8,您可以简单地使用 LAG()LEAD() window 函数。


对于 MySQL5.x 你没有那个,所以可以使用相关子查询,例如...

SELECT 
    -- *,
    (SELECT date_created FROM historical WHERE date_created < h.date_created ORDER BY date_Created DESC LIMIT 1)  AS prev_date_created,
    -- (select date_created where id = h.id and pci_s = h.pci_s + 1) as dc,
    h.id,
    h.date_created,
    CONCAT('B', h.pci_b) AS batch,
    h.pci_s,
    DATEDIFF(h.date_created, h.date_created) as days_in_stage
FROM
    historical h
WHERE
    h.pci_b = 1
ORDER BY
    h.date_created
;

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=0ce3b601688e1de11eda1007bffea9f9

在 mysql 的新版本中,您可以使用 Lead 和 Lag 函数来获取下一行和上一行数据。但是如果你没有使用当前版本那么这将不起作用,还有其他解决方案。

如果不使用新版本,请分享您的 mysql 版本。

例如新版本:

SELECT 
    -- *,
    h.date_created,
    -- (select date_created where id = h.id and pci_s = h.pci_s + 1) as dc,
    h.id,
    h.date_created,
    CONCAT('B', h.pci_b) AS batch,
    h.pci_s,
    DATEDIFF(h.date_created, h.date_created) as days_in_stage, 
    lead(h.date_created)over (order by h.date_created) next_row_date,
    lag(h.date_created)over (order by h.date_created) pre_row_date
FROM
    historical h
WHERE
    h.pci_b = 1
;

I get the succeeding or previous data row result

您正在寻找 LEADLAG window 函数。

但是你的MySQL版本低于8.0,不支持window功能。

您可以尝试使用子查询来实现 LEADLAG window 函数。

查询 1:

SELECT 
    h.date_created,
    h.id,
    h.date_created,
    CONCAT('B', h.pci_b) AS batch,
    h.pci_s,
    COALESCE(DATEDIFF(h.date_created,(
        SELECT hh.date_created
        FROM historical hh
        WHERE h.pci_b = hh.pci_b AND h.date_created > hh.date_created
        ORDER BY hh.date_created DESC
        LIMIT 1
    )),0) as days_in_stage
FROM
    historical h
WHERE
    h.pci_b = 1

Results:

|         date_created | id |         date_created | batch | pci_s | days_in_stage |
|----------------------|----|----------------------|-------|-------|---------------|
| 2021-07-18T06:32:26Z |  1 | 2021-07-18T06:32:26Z |    B1 |     0 |             0 |
| 2021-07-20T06:32:26Z |  4 | 2021-07-20T06:32:26Z |    B1 |     1 |             2 |