SQL查询要逐行进行比较

时间:2014-03-25 18:05:10

标签: sql sql-server sql-server-2012

我有桌子:

        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

3 个答案:

答案 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)