Reputation: 15
:-Need help in sql query for updating a table
update query- set END_DATE of first record should be the start date of second record, for a particular id .-as highlighted in yellow(order by start date ).
Also the final record for each id ( in this case for id=1&2 , record with end date 12/31/9999 should not touch and leave as it is. How to do that?
Upvotes: 0
Views: 762
Reputation: 1038
With SQL Server, another way is to use common table expressions (CTE):
; WITH myTableExt AS (
SELECT *, ROW_NUMBER() OVER( PARTITION BY id ORDER BY id, startDate ) AS rowNo
FROM myTable
WHERE 1 = 1
)
UPDATE a
SET a.endDate = DATEADD( day, -1, b.startDate )
FROM myTableExt a
INNER JOIN myTableExt b ON a.id = b.id
AND a.rowNo = b.rowNo - 1
WHERE 1 = 1
The first part uses a CTE to generate the original table but extended with the row-No 1..N for the rows in the date sequence grouped-by id & ordered-by date.
To clarify, this shows the generated CTE:
; WITH myTableExt AS (
SELECT *, ROW_NUMBER() OVER( PARTITION BY id ORDER BY id, startDate ) AS rowNo
FROM myTable
WHERE 1 = 1
)
SELECT * FROM myTableExt
The second part uses the generated CTE to update the actual table with a self-join on itself to set the end-date for row(N) to one day before the start-date of row(N+1).
The rows with the 'last' start dates are not updated as there will not be a match on the next row in the CTE.
Upvotes: 0
Reputation: 381
If you have SQL Server 2016+ you can use the LEAD function.
UPDATE MyTable
SET [END_DATE] = COALESCE([DesiredData].END_DATE, '9999-12-31')
FROM MyTable
INNER JOIN ( SELECT
[id],
[START_DATE],
LEAD([START_DATE]) OVER(PARTITION BY [id], ORDER BY [START_DATE]) [END_DATE]
FROM MyTable
) AS [DesiredData]
ON MyTable.[id] = [DesiredData].[id]
AND MyTable.[START_DATE] = [DesiredData].[START_DATE]
If you do not, you could do a correlated subquery:
UPDATE MyTable
SET [END_DATE] = COALESCE(
( SELECT TOP 1 END_DATE
FROM MyTable [NextRecord]
WHERE [NextRecord].[id] = MyTable.id
AND [NextRecord].[START_DATE] > MyTable.[START_DATE]
ORDER BY NextRecord.[START_DATE]
),
'9999-12-31'
)
Upvotes: 2