2014-03-25 97 views
1

我有表:SQL查詢做逐行比較

 opendt  enddt   Id 
     ------------------------------ 
     2013-01-20 2013-02-20 1 
     2013-02-20 2014-02-06 1 
     2013-02-28 NULL   1 

理想備案#2,我們應該有enddt = 2013-02-28而是它是2014-02-06錯誤。我想查找enddt與下一行opendt相同的ID。我知道我可以嘗試使用temp表來查找。沒有temp表有沒有辦法做到這一點? SQL 2012

+0

是的!等我寫了SQL – AK47

+1

你做了什麼事嗎? – KrazzyNefarious

+0

你用什麼SQL Server版本? –

回答

4

您正在使用SQL Server 2012,所以我會建議使用lead()

select t.* 
from (select t.*, lead(opendt) over (partition by id order by opendt) as next_opendt 
     from table t 
    ) t 
where next_opendt <> enddt; 
2

試試這個,

;With CTE as 
    (
     Select *,row_number() over (partition by id order by opendt asc) as rNo from myTable as t1 
    ) 
    select * from CTE as a 
    left join CTE as b on a.rNo =b.rNo + 1 and a.id=b.id 
    where b.opendt <> a.enddt 
+0

檢查你的語法。 –

+0

糾正了一個錯誤,謝謝!現在不是SQl服務器的前臺。還有任何錯誤,請糾正我。 – AK47

+0

我認爲你還需要通過ID加入,否則,id = 1的最後一條記錄將與id = 2的第一條記錄進行比較... –

1

我試圖用非CTE的方式來做到這一點。我使用子查詢,並在代碼中標記了它們。我不確定是否最好。這個答案是一個數據庫不可知論者。

這個查詢幫助我們爲更新選擇數據 -

select ini.id, 
ini.maxend as opendt, 
fin.opendt as enddt 
from 
(
select id, MAX(opendt) maxend 
from mytable 
where enddt is not null 
group by id 
) as ini -- subquery 1 
inner join 
(
select id, opendt 
from mytable 
where enddt is null 
) as fin -- subquery 2 
on ini.id = fin.id 

現在我們將使用上面的查詢更新主表 -

從這樣的選擇更新的通用查詢像這 -

update t1 
set 
t1.enddt = t2.enddt 
from mytable as t1 
inner join (Something) as t2 -- something is a table or select 
on (some-condition) 
where (some-column = whatever) 

這個是最終的結果 -

update t1 
set 
t1.enddt = t2.enddt 
--select * 
from mytable as t1 
inner join 
(
select ini.id, 
ini.maxend as opendt, 
fin.opendt as enddt 
from 
(
select id, MAX(opendt) maxend 
from mytable 
where enddt is not null 
group by id 
) as ini -- subquery 1 
inner join 
(
select id, opendt 
from mytable 
where enddt is null 
) as fin -- subquery 2 
on ini.id = fin.id 
) as t2 
on t1.id = t2.id 
and t1.opendt = t2.opendt 

示例表和行 -

CREATE TABLE [dbo].[mytable](
    [opendt] [date] NULL, 
    [enddt] [date] NULL, 
    [id] [int] NULL 
) 
GO 
INSERT [dbo].[mytable] ([opendt], [enddt], [id]) 
VALUES (CAST(0xA7360B00 AS Date), CAST(0xC6360B00 AS Date), 1) 
INSERT [dbo].[mytable] ([opendt], [enddt], [id]) 
VALUES (CAST(0xC6360B00 AS Date), CAST(0x25380B00 AS Date), 1) 
INSERT [dbo].[mytable] ([opendt], [enddt], [id]) 
VALUES (CAST(0xCE360B00 AS Date), NULL, 1) 
INSERT [dbo].[mytable] ([opendt], [enddt], [id]) 
VALUES (CAST(0x49370B00 AS Date), CAST(0x4D370B00 AS Date), 2) 
INSERT [dbo].[mytable] ([opendt], [enddt], [id]) 
VALUES (CAST(0x4D370B00 AS Date), CAST(0x50370B00 AS Date), 2) 
INSERT [dbo].[mytable] ([opendt], [enddt], [id]) 
VALUES (CAST(0x57370B00 AS Date), NULL, 2)