I have a table with this format
From | To | Begin_Date |
---|---|---|
B | A | 1220201 |
C | A | 1220301 |
B | A | 1220102 |
A | B | 1220201 |
C | B | 1220301 |
A | B | 1220101 |
The date format is formatted like this : 1yymmdd
What I want is for each From
and To
couple (per example A
/B
) create a Begin_Date
and End_Date
(based on the next Begin_Date
) with the Format dd.mm.yy
.
I already have the Begin_date
since its the value given by the user. Now, for the End_Date
, I have to check if there's a Begin_date
bigger than my from/to couple.
Per exemple, for the A
/B
:
From | To | Begin_Date |
---|---|---|
A | B | 01.02.2022 |
A | B | 01.01.2022 |
It should gave me something like this (the result that I want at the end with all the from/to couple) :
From | To | Begin_Date | End_Date |
---|---|---|---|
A | B | 01.02.2022 | null |
A | B | 01.01.2022 | 31.01.2022 |
The value End_date
is 31.01.2022
because there's a bigger value for this couple (01.02.2022
) and it's a day before this value.
And if there's no bigger Begin_date
, I just want to write null
.
Can you help me to do this ? I couldn't find a viable solution for this use case.
CodePudding user response:
You should consider storing dates in a Date Column, not in a varchar column.
Maybe this is what you are after ?
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
If this is not exact what you want, then please try to explain in more detail
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 |
CodePudding user response:
you can use lead()
or lag()
to get the next / previous value and then dateadd()
to subtract one day from it.
Conversion of your dateformat 1YYMMDD
to date
is done in the 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]