以下循环根据同一个表中是否存在其他记录有条件地设置@EndDate。基本上,如果给定的ReferenceTypeId和每个PersonId,KeepId和RemoveId至少存在一条记录,我们只想将当前日期分配给@EndDate。
如何在没有循环的情况下编写此Update语句。
DECLARE ReferenceType_Cursor CURSOR FOR
SELECT ID FROM CORE.PersonExternalReferenceType
OPEN ReferenceType_Cursor
FETCH NEXT FROM ReferenceType_Cursor INTO @RefTypeId
WHILE @@FETCH_STATUS = 0
BEGIN
SET @ENDDATE = NULL
IF( EXISTS (SELECT 1 FROM CORE.PersonExternalReferences WHERE ReferenceTypeId = @RefTypeId AND PersonId = @KeepId) AND
EXISTS (SELECT 1 FROM CORE.PersonExternalReferences WHERE ReferenceTypeId = @RefTypeId AND PersonId = @RemoveId))
BEGIN
SET @ENDDATE = @CURRENTDATE
END
UPDATE CORE.PersonExternalReferences
SET
PersonId = @KeepID,
ModifiedBy = @USERNAME,
ModifiedDate = @CURRENTDATE,
StartDate = COALESCE(StartDate,CreatedDate,@STARTDATE),
EndDate = @ENDDATE
WHERE ReferenceTypeId = @RefTypeId AND PersonId = @RemoveID
FETCH NEXT FROM ReferenceType_Cursor INTO @RefTypeId
END
CLOSE ReferenceType_Cursor
DEALLOCATE ReferenceType_Cursor
答案 0 :(得分:1)
只是为了澄清你的要求:
您想要更新PersonId = @RemoveID的每个PersonExternalReferences。
对于每个记录,检查是否存在另一个具有相同ReferenceTypeId 和PersonId = @KeepId的PersonExternalReferences 。如果存在,则设置EndDate = @ENDDATE,否则设置EndDate = null。
为了确保它是正常工作的代码,我创建了一个简化的准备运行示例。
架构设置为:
create table PersonExternalReferenceType (
id varchar(100)
)
go
create table PersonExternalReferences (
PersonId int,
ReferenceTypeId varchar(100),
ModifiedDate datetime,
EndDate datetime
)
go
insert PersonExternalReferenceType
values ('foo'),('bar')
;
insert PersonExternalReferences
values
(1,'foo',null,null),
(2,'foo',null,null),
(3,'foo',null,null),
(4,'bar',null,null)
;
实际的更新声明是
declare @KeepId int = 1;
declare @RemoveId int = 2;
update PersonExternalReferences
set ModifiedDate = getdate(),
EndDate = case when exists (
select 1 from PersonExternalReferences as other
where other.PersonId = @KeepId
and other.ReferenceTypeId = PersonExternalReferences.ReferenceTypeId
) then getdate() else null end
where PersonId = @RemoveId;
然后再次使用
运行declare @KeepId int = 3;
declare @RemoveId int = 4;
最终结果是
+----------+-----------------+-------------------------+-------------------------+
| PersonId | ReferenceTypeId | ModifiedDate | EndDate |
+----------+-----------------+-------------------------+-------------------------+
| 1 | foo | NULL | NULL |
| 2 | foo | 2016-03-03 10:27:40.507 | 2016-03-03 10:27:40.507 |
| 3 | foo | NULL | NULL |
| 4 | bar | 2016-03-03 10:27:40.517 | NULL |
+----------+-----------------+-------------------------+-------------------------+
答案 1 :(得分:0)
@CURRENTDATE
UPDATE CORE.PersonExternalReferences
SET
PersonId = @KeepID,
ModifiedBy = @USERNAME,
ModifiedDate = @CURRENTDATE,
StartDate = COALESCE(StartDate,CreatedDate,@STARTDATE),
EndDate =
case when (ReferenceTypeId = @RefTypeId
AND PersonId = @KeepId
and PersonID = @RemoveId) then
@CURRENTDATE
else null end
/*Then you don't need to filter at all if you wanna loop trought whole table... WHERE ReferenceTypeId = @RefTypeId AND PersonId = @RemoveID
*/

答案 2 :(得分:0)
我有两个解决方案。您只需根据需要编辑分区列和列:
update a
set a.enddate = @enddate
from abc as a
where ReferenceTypeId = @RefTypeId AND PersonId = @RemoveID and
exists(select 1 from abc as b where b.ReferenceTypeId = a.ReferenceTypeId group by ReferenceTypeId,PersonId,KeepId,RemoveId having count(*) >1)
另一个:
update a
set a.enddate = @enddate
from
(
select *, count(*) over (partition by ReferenceTypeId,PersonId,KeepId,RemoveId) as rn
from abc
) as a
where a.rn > 1 and ReferenceTypeId = @RefTypeId AND PersonId = @RemoveID
如果这有帮助,请告诉我。