将下一行的日期用作当前行的结束日期

时间:2019-09-23 08:32:08

标签: mysql sql

我的桌子布置如下:

ID | FOCUS      | DATE
----------------------------
 1 | equipment  | 2018-01-01
 2 | uniform    | 2018-02-14
 3 | attendance | 2018-04-03

在引入新焦点时添加行。

我希望能够获得特定焦点的开始日期和结束日期,假设它在下一个焦点开始时结束。处理如下视图:

ID | FOCUS      | STARTDATE  | ENDDATE
--------------------------------------
 1 | equipment  | 2018-01-01 | 2018-02-14
 2 | uniform    | 2018-02-14 | 2018-04-03
 3 | attendance | 2018-04-03 | NULL

我正在使用的数据库没有LEAD或LAG函数,因此我需要一种在纯SQL中执行此操作的方法。到目前为止,我发现的所有解决方案都使用LEAD和LAG。有什么想法吗?

4 个答案:

答案 0 :(得分:3)

您可以通过LEFT JOIN将表自身设置为自己获得所需的结果,右表的日期是大于左表的日期的最小日期值。无论ID的值是连续的,此查询都将起作用:

SELECT t1.ID, t1.FOCUS, t1.DATE AS STARTDATE, t2.DATE AS ENDDATE
FROM table1 t1
LEFT JOIN table1 t2 ON t2.DATE = (SELECT MIN(DATE)
                                  FROM table1 t3
                                  WHERE t3.DATE > t1.DATE)

输出:

ID  FOCUS       STARTDATE   ENDDATE
1   equipment   2018-01-01  2018-02-14
2   uniform     2018-02-14  2018-04-03
3   attendance  2018-04-03  null

Demo on dbfiddle

如果两个事件有可能在同一天结束,则可以按以下方式修改查询,只要ID值随DATE值的增加而增加,查询将起作用。

SELECT DISTINCT t1.ID, t1.FOCUS, t1.DATE AS STARTDATE, t2.DATE AS ENDDATE
FROM table1 t1
LEFT JOIN table1 t2 ON t2.DATE = (SELECT MIN(DATE)
                                  FROM table1 t3
                                  WHERE t3.DATE >= t1.DATE AND t3.ID > t1.ID)

Demo on dbfiddle

答案 1 :(得分:1)

这应该做

select t.id, t.focus, t.date as startdate, t2.date as enddate 
from 
   (select focus, date, row_number() over (order by date asc)  as rn 
    from tableA) t
left join 
   (select focus, date, row_number() over (order by date asc) as rn from tableA) t2
       on t2.rn + 1 = t.rn

答案 2 :(得分:1)

没有LEAD和LAG,您可以使用子查询来编写它,该子查询将从ID + 1行中获取日期,如下所示:

SELECT qry.id
     , qry.focus
     , qry.date as startdate
     , (select sbq.date from your_table sbq where sbq.id = (qry.id + 1)) as enddate
  FROM your_table qry

答案 3 :(得分:0)

我只使用相关子查询:

select t.*,
       (select min(t2.date)
        from t t2
        where t2.date > t.date
       ) as enddate
from t;

如果日期相同,则可以使用id来区分值。那应该是:

select t.*,
       (select t2.date
        from t t2
        where t2.date > t.date or
              (t2.date = t.date and t2.id > t.id)
        order by t2.date asc, t2.id asc
        fetch first 1 row only
       ) as enddate
from t;

注意:您未指定正在使用的数据库。 fetch first是标准SQL;一些数据库使用limit,另一些数据库使用select top