如何根据当前的“开始日期”和下一个(如果存在)创建“开始日期”和“结束日期”
How can I create a `begin date` and `end date` based on the current `begin date` and the next one (if exists)
我有一个 table 这种格式
From
To
Begin_Date
B
A
1220201
C
A
1220301
B
A
1220102
A
B
1220201
C
B
1220301
A
B
1220101
日期格式如下:1yymmdd
我想要的是为每个 From
和 To
对(每个示例 A
/B
)创建一个 Begin_Date
和 End_Date
(基于下一个 Begin_Date
),格式为 dd.mm.yy
.
我已经有了 Begin_date
,因为它是用户给出的值。现在,对于 End_Date
,我必须检查是否有 Begin_date
比我的 from/to 夫妇大。
例如,对于 A
/B
:
From
To
Begin_Date
A
B
01.02.2022
A
B
01.01.2022
它应该给了我这样的东西(最后我想要所有 from/to 对的结果):
From
To
Begin_Date
End_Date
A
B
01.02.2022
null
A
B
01.01.2022
31.01.2022
值 End_date
是 31.01.2022
因为这对夫妇 (01.02.2022
) 的值更大,而且比这个值早一天。
如果没有更大的Begin_date
,我只想写null
。
你能帮我做这个吗?我找不到适用于此用例的可行解决方案。
您应该考虑将日期存储在日期列中,而不是 varchar 列中。
也许这就是您想要的?
select t.[From],
t.[To],
convert(date, right(t.Begin_Date, 6)) as BeginDate,
t2.BeginDate as EndDate
from table1 t
outer apply ( select top 1
dateadd(day, -1, convert(date, right(t1.Begin_Date, 6))) as BeginDate
from table1 t1
where t1.[From] = t.[From]
and t1.[To] = t.[To]
and convert(date, right(t1.Begin_Date, 6)) > convert(date, right(t.Begin_Date, 6))
order by convert(date, right(t1.Begin_Date, 6))
) t2
Click on this link to see it in DBFiddle
如果这不是您想要的,请尝试更详细地解释
From
To
BeginDate
EndDate
B
A
2022-02-01
C
A
2022-03-01
B
A
2022-01-02
2022-01-31
A
B
2022-02-01
C
B
2022-03-01
A
B
2022-01-02
2022-01-31
您可以使用 lead()
or lag()
获取下一个/上一个值,然后 dateadd()
从中减去一天。
日期格式 1YYMMDD
到 date
的转换在 CROSS APPLY
中完成
select *,
EndDate = dateadd(day, -1, lead(b.BeginDate) over (partition by t.[From], t.[To]
order by b.BeginDate) )
from tbl t
cross apply
(
select BeginDate = convert(date, '20' + right(t.[Begin_Date], 6))
) b
order by t.[From], t.[To], b.[BeginDate]
我有一个 table 这种格式
From | To | Begin_Date |
---|---|---|
B | A | 1220201 |
C | A | 1220301 |
B | A | 1220102 |
A | B | 1220201 |
C | B | 1220301 |
A | B | 1220101 |
日期格式如下:1yymmdd
我想要的是为每个 From
和 To
对(每个示例 A
/B
)创建一个 Begin_Date
和 End_Date
(基于下一个 Begin_Date
),格式为 dd.mm.yy
.
我已经有了 Begin_date
,因为它是用户给出的值。现在,对于 End_Date
,我必须检查是否有 Begin_date
比我的 from/to 夫妇大。
例如,对于 A
/B
:
From | To | Begin_Date |
---|---|---|
A | B | 01.02.2022 |
A | B | 01.01.2022 |
它应该给了我这样的东西(最后我想要所有 from/to 对的结果):
From | To | Begin_Date | End_Date |
---|---|---|---|
A | B | 01.02.2022 | null |
A | B | 01.01.2022 | 31.01.2022 |
值 End_date
是 31.01.2022
因为这对夫妇 (01.02.2022
) 的值更大,而且比这个值早一天。
如果没有更大的Begin_date
,我只想写null
。
你能帮我做这个吗?我找不到适用于此用例的可行解决方案。
您应该考虑将日期存储在日期列中,而不是 varchar 列中。
也许这就是您想要的?
select t.[From],
t.[To],
convert(date, right(t.Begin_Date, 6)) as BeginDate,
t2.BeginDate as EndDate
from table1 t
outer apply ( select top 1
dateadd(day, -1, convert(date, right(t1.Begin_Date, 6))) as BeginDate
from table1 t1
where t1.[From] = t.[From]
and t1.[To] = t.[To]
and convert(date, right(t1.Begin_Date, 6)) > convert(date, right(t.Begin_Date, 6))
order by convert(date, right(t1.Begin_Date, 6))
) t2
Click on this link to see it in DBFiddle
如果这不是您想要的,请尝试更详细地解释
From | To | BeginDate | EndDate |
---|---|---|---|
B | A | 2022-02-01 | |
C | A | 2022-03-01 | |
B | A | 2022-01-02 | 2022-01-31 |
A | B | 2022-02-01 | |
C | B | 2022-03-01 | |
A | B | 2022-01-02 | 2022-01-31 |
您可以使用 lead()
or lag()
获取下一个/上一个值,然后 dateadd()
从中减去一天。
日期格式 1YYMMDD
到 date
的转换在 CROSS APPLY
select *,
EndDate = dateadd(day, -1, lead(b.BeginDate) over (partition by t.[From], t.[To]
order by b.BeginDate) )
from tbl t
cross apply
(
select BeginDate = convert(date, '20' + right(t.[Begin_Date], 6))
) b
order by t.[From], t.[To], b.[BeginDate]