我有桌子:
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 :(得分: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;
答案 1 :(得分: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
答案 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)