here is the example table with data (rn column is ROW_NUMBER() for each UELN).
UELN OwnerID Date rn
191001180010389 017581 1989-06-30 00:00:00.000 1
191001180010389 017747 2011-06-02 00:00:00.000 2
191001180010389 017992 2014-03-25 00:00:00.000 3
191001180010389 117030 2015-02-03 00:00:00.000 4
191001250009303 018148 2004-06-30 00:00:00.000 1
191001250009303 018418 2013-10-16 00:00:00.000 2
I need to combine those rows to get result set like this:
UELN OwnerID DateFrom DateTo
191001180010389 017581 1989-06-30 00:00:00.000 2011-06-02 00:00:00.000
191001180010389 017747 2011-06-02 00:00:00.000 2014-03-25 00:00:00.000
191001180010389 017992 2014-03-25 00:00:00.000 2015-02-03 00:00:00.000
191001180010389 117030 2015-02-03 00:00:00.000 NULL
191001250009303 018148 2004-06-30 00:00:00.000 2013-10-16 00:00:00.000
191001250009303 018418 2013-10-16 00:00:00.000 NULL
NULL in DateTo column means that this is still valid.
Can anyone help me with the query?
答案 0 :(得分:3)
select u1.*, u2.date as [date to]
from tabl u1
left join tabl u2
on u1.UELN = u2.UELN
and u2.rn = u1.rn + 1
You just need a left self join
The left part is what gets the null date for the no match
答案 1 :(得分:2)
Using OUTER APPLY
:
SELECT
t.UELN,
t.OwnerID,
DateFrom = t.[Date],
DateTo = x.DateTo
FROM tbl t
OUTER APPLY(
SELECT
DateTo = [Date]
FROM tbl
WHERE
UELN = t.UELN
AND rn = t.rn + 1
)x
答案 2 :(得分:0)
You can try the following:
-- Create demo data
CREATE TABLE #temp(ueln bigint, ownerid nvarchar(20), date date, rn int)
INSERT INTO #temp(ueln, ownerid, date, rn)
VALUES (191001180010389,N'017581', N'1989-06-30 00:00:00.000', 1),
(191001180010389,N'017747', N'2011-06-02 00:00:00.000', 2),
(191001180010389,N'017992', N'2014-03-25 00:00:00.000', 3),
(191001180010389,N'117030', N'2015-02-03 00:00:00.000', 4),
(191001250009303,N'018148', N'2004-06-30 00:00:00.000', 1),
(191001250009303,N'018148', N'2013-10-16 00:00:00.000', 2)
-- your part
SELECT cur.ueln, cur.ownerid, cur.date as date_from, due.date as date_to
-- Maybe 1 day befor: DATEADD(day,-1,due.date) as date_to
FROM #temp as cur
LEFT JOIN #temp as due
ON cur.ueln = due.ueln
AND cur.rn = due.rn+1
DROP TABLE #temp
Which results in:
ueln ownerid date_from date_to
-------------------- -------------------- ---------- ----------
191001180010389 017581 1989-06-30 NULL
191001180010389 017747 2011-06-02 1989-06-30
191001180010389 017992 2014-03-25 2011-06-02
191001180010389 117030 2015-02-03 2014-03-25
191001250009303 018148 2004-06-30 NULL
191001250009303 018148 2013-10-16 2004-06-30
If you want to be the date_to one day before the next data-row, you can use the commented date_to
.
答案 3 :(得分:0)
我们可以使用SQL 2012中引入的LEAD()
函数。
--setup
CREATE TABLE #temp(ueln bigint, ownerid nvarchar(20), [date] date)
INSERT INTO #temp(ueln, ownerid, [date])
VALUES (191001180010389, N'017581', N'1989-06-30 00:00:00.000'),
(191001180010389, N'017747', N'2011-06-02 00:00:00.000'),
(191001180010389, N'017992', N'2014-03-25 00:00:00.000'),
(191001180010389, N'117030', N'2015-02-03 00:00:00.000'),
(191001250009303, N'018148', N'2004-06-30 00:00:00.000'),
(191001250009303, N'018148', N'2013-10-16 00:00:00.000');
--actual query
SELECT [ueln] ,
[ownerid] ,
[date] AS [DateFrom]
, LEAD([date], 1) OVER (PARTITION BY ueln ORDER BY [date]) AS [DateTo]
FROM #temp
感谢@Ionic的临时表定义!