所以我在SQL-Server 2008中有一个名为Member_Phys_History
的历史表
看起来像这样:
RecID, MemberID, Phys_ID, Phys_Start, Phys_End, Phys_Update
第一列是identity
,Phys_Start
,Phys_End
和Phys_Update
是日期。
我有另一张名为Member_Phys_Update
MemberID, Phys_ID, Phys_Start_Date
因此,每周大约一次,这个Update表会从客户端获得更新,其中Phys_ID发生变化,Phys_start会更晚......所以我将此信息添加到History表中,它看起来像这样:
1|ABC123|555|2014-01-01|NULL|NULL
2|ABC123|556|2014-04-01|NULL|NULL
以下是我需要做的事情:
我希望基本上将第一条记录Phys_End_Date设置为第二条记录Phys_Start_Date
前一天。所以它看起来像这样:
1|ABC123|555|2014-01-01|2014-03-30|NULL
2|ABC123|556|2014-04-01|NULL|NULL
遗憾的是,我无法使用光标存储过程,我的DBA认为它效率低下。我想知道在几次查询中是否有任何办法可以做到这一点......
光标可能是理想的,但我可以使用FETCH NEXT或其他东西吗?
答案 0 :(得分:4)
试试这个
Select A.*, B.Phys_End_Date
from table1 A
outer apply (select (min(Phys_Start_Date) - 1) Phys_End_Date from table1 x
where x.Phys_Start_Date > A.Phys_Start_Date
AND X.MemberID = A.MemberID) B
编辑(添加更新SQL)
update A
set A.Phys_End_Date = B.Phys_End_Date
from table1 A
outer apply (select (min(Phys_Start_Date) - 1) Phys_End_Date from table1 x
where x.Phys_Start_Date > A.Phys_Start_Date
AND X.MemberID = A.MemberID) B
or
INSERT INTO table2 (memberid, phys_id,Phys_Start_Date,Phys_End_Date)
Select A.*, B.Phys_End_Date
from table1 A
outer apply (select (min(Phys_Start_Date) - 1) Phys_End_Date from table1 x
where x.Phys_Start_Date > A.Phys_Start_Date
AND X.MemberID = A.MemberID) B;
答案 1 :(得分:2)
作为替代方案,您可以使用Common Table表达式来完成它。
;WITH base
AS (
SELECT *
,ROW_NUMBER() OVER ( PARTITION BY MemberID ORDER BY Phys_Start ASC ) AS rn
FROM Member_Phys_History
),
nextDate
AS (
SELECT *
,ROW_NUMBER() OVER ( PARTITION BY MemberID ORDER BY Phys_Start ASC ) AS rn
FROM Member_Phys_History
)
SELECT b.RecID
,b.MemberID
,b.Phys_ID
,b.Phys_Start
,DATEADD(dd, -1, n.Phys_Start) AS Phy_End
,b.Phys_Update
FROM base AS b
LEFT OUTER JOIN nextDate AS n
ON b.MemberID = n.MemberID
AND b.rn = n.rn - 1;
将它变成UPDATE
陈述
;WITH base
AS (
SELECT *
,ROW_NUMBER() OVER ( PARTITION BY MemberID ORDER BY Phys_Start ASC ) AS rn
FROM Member_Phys_History
),
nextDate
AS (
SELECT *
,ROW_NUMBER() OVER ( PARTITION BY MemberID ORDER BY Phys_Start ASC ) AS rn
FROM Member_Phys_History
)
UPDATE b
SET b.Phys_End = DATEADD(dd, -1, n.Phys_Start)
FROM base AS b
LEFT OUTER JOIN nextDate AS n
ON b.MemberID = n.MemberID
AND b.rn = n.rn - 1;
答案 2 :(得分:0)
SQL小提琴 -
您不会在此处看到所有选择列。在您的SQL Server中运行它。 http://sqlfiddle.com/#!3/75dca/2
限制 - 仅当Phys_ID(您的表格)或代码(我的表格)是连续数字时,我的代码才有效。
自我加入的另一种方式 -
select *
from tblz as t1
inner join tblz as t2
on t1.id = t2.id
and (t1.code = t2.code - 1)
使用上述查询进行更新 -
update t1
set t1.EndDate = Dateadd(DAY, -1, t2.StartDate)
--select *
from tblz as t1
inner join tblz as t2
on t1.id = t2.id
and (t1.code = t2.code - 1)