我的桌子布置如下:
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。有什么想法吗?
答案 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
如果两个事件有可能在同一天结束,则可以按以下方式修改查询,只要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)
答案 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
。