更新 SQL 服务器中的另一个行值
Update another row value in SQL Server
我有一个 table,名称、位置、开始日期和结束日期如下:
+------+----------+-----------+-----------+-----------+
| name | location | startdate | endate | is_active |
+------+----------+-----------+-----------+-----------+
| A | delhi | 3/26/2019 | 3/26/2019 | 1 |
| A | delhi | 3/27/2019 | 3/27/2019 | 1 |
| A | delhi | 3/28/2019 | 3/28/2019 | 1 |
| A | delhi | 3/31/2019 | 3/31/2019 | 1 |
+------+----------+-----------+-----------+-----------+
需要这样更新:
+------+----------+-----------+-----------+-----------+
| name | location | startdate | endate | is_active |
+------+----------+-----------+-----------+-----------+
| A | delhi | 3/26/2019 | 3/28/2019 | 1 |
| A | delhi | 3/27/2019 | 3/27/2019 | 0 |
| A | delhi | 3/28/2019 | 3/28/2019 | 0 |
| A | delhi | 3/31/2019 | 3/31/2019 | 1 |
+------+----------+-----------+-----------+-----------+
如果 startdate
是连续的,则使用最后一个连续 startdate
的结束日期更新结束日期,并更新 is_active = 0
连续开始日期
这是一个缺口和孤岛问题。这是一种使用 lag()
和累积 sum()
来定义组的方法。最后一步是条件逻辑:
select
name,
location,
startdate,
case when row_number() over(partition by name, location, grp order by startdate) = 1
then max(startdate) over(partition by name, location, grp)
else enddate
end as enddate,
case when row_number() over(partition by name, location, grp order by startdate) = 1
then 1
else 0
end as is_active
from (
select
t.*,
sum(case when startdate = dateadd(day, 1, lag_enddate) then 0 else 1 end)
over(partition by name, location order by startdate) grp
from (
select
t.*,
lag(enddate) over(partition by name, location order by startdate) lag_enddate
from mytable t
) t
) t
name | location | startdate | enddate | is_active
:--- | :------- | :--------- | :--------- | --------:
A | delhi | 2019-03-26 | 2019-03-28 | 1
A | delhi | 2019-03-27 | 2019-03-27 | 0
A | delhi | 2019-03-28 | 2019-03-28 | 0
A | delhi | 2019-03-31 | 2019-03-31 | 1
我有一个 table,名称、位置、开始日期和结束日期如下:
+------+----------+-----------+-----------+-----------+
| name | location | startdate | endate | is_active |
+------+----------+-----------+-----------+-----------+
| A | delhi | 3/26/2019 | 3/26/2019 | 1 |
| A | delhi | 3/27/2019 | 3/27/2019 | 1 |
| A | delhi | 3/28/2019 | 3/28/2019 | 1 |
| A | delhi | 3/31/2019 | 3/31/2019 | 1 |
+------+----------+-----------+-----------+-----------+
需要这样更新:
+------+----------+-----------+-----------+-----------+
| name | location | startdate | endate | is_active |
+------+----------+-----------+-----------+-----------+
| A | delhi | 3/26/2019 | 3/28/2019 | 1 |
| A | delhi | 3/27/2019 | 3/27/2019 | 0 |
| A | delhi | 3/28/2019 | 3/28/2019 | 0 |
| A | delhi | 3/31/2019 | 3/31/2019 | 1 |
+------+----------+-----------+-----------+-----------+
如果 startdate
是连续的,则使用最后一个连续 startdate
的结束日期更新结束日期,并更新 is_active = 0
连续开始日期
这是一个缺口和孤岛问题。这是一种使用 lag()
和累积 sum()
来定义组的方法。最后一步是条件逻辑:
select
name,
location,
startdate,
case when row_number() over(partition by name, location, grp order by startdate) = 1
then max(startdate) over(partition by name, location, grp)
else enddate
end as enddate,
case when row_number() over(partition by name, location, grp order by startdate) = 1
then 1
else 0
end as is_active
from (
select
t.*,
sum(case when startdate = dateadd(day, 1, lag_enddate) then 0 else 1 end)
over(partition by name, location order by startdate) grp
from (
select
t.*,
lag(enddate) over(partition by name, location order by startdate) lag_enddate
from mytable t
) t
) t
name | location | startdate | enddate | is_active :--- | :------- | :--------- | :--------- | --------: A | delhi | 2019-03-26 | 2019-03-28 | 1 A | delhi | 2019-03-27 | 2019-03-27 | 0 A | delhi | 2019-03-28 | 2019-03-28 | 0 A | delhi | 2019-03-31 | 2019-03-31 | 1