【发布时间】:2018-01-05 18:54:25
【问题描述】:
我有一个光标,我想把它变成一个 CTE。
我要避免的是循环逻辑。它的作用是,它取回所有特定的“文件夹”,然后循环检查新文件夹 ID = 旧文件夹 ID,如果是,则设置 DupCheck = 1,否则设置 DupCheck = 0。
当它循环时,它不会在 folderid 第一次更改时将 DupCheck 设置为 1,只是在每个后续文件夹上设置,直到 folderid 再次更改。这样一来,那组folderids只有第一条记录是DupCheck=0,后面的都是1(因为是重复的)……有意义吗?
我不太能够准确地看到解决方案。需要一点帮助。
这是旧的光标,以及到目前为止我所拥有的新 CTE。
旧代码(光标):
-- old cursor
declare @DFolderId int, @DItemID int
declare @Dname varchar(100)
declare @DFolderIdNew int
set @DFolderIdNew = 0
declare CurDup cursor for
select FolderID, EntityName, ItemID
from @TempTable
where FolderID in (select FolderID
from @TempTable
group by FolderID
having count(*) > 1)
order by FolderID, EntityType
open CurDup
fetch next from CurDup into @DFolderId, @Dname, @DItemID
while @@FETCH_STATUS = 0
begin
if @DFolderIdNew = @DFolderId
begin
update @TempTable
set DupCheck = 1
where FolderID = @DFolderId and ItemID = @DItemID
end
else
begin
update @TempTable
set DupCheck = 0
where FolderID = @DFolderId and ItemID = @DItemID
end
set @DFolderIdNew = @DFolderId
fetch next from CurDup into @DFolderId, @Dname, @DItemID
end
close CurDup
deallocate CurDup
CTE 替换
-- CTE replacement for cursor
;WITH cteCurDup (FolderID, EntityName, EntityType, ItemID, RowNum) AS
(
SELECT
FolderID, EntityName, Entitytype, ItemID,
ROW_NUMBER() OVER (ORDER BY FolderID, EntityType) AS RowNum
FROM
@TempTable
WHERE
FolderID IN (SELECT FolderID
FROM @TempTable
GROUP BY FolderID
HAVING COUNT(*) > 1)
-- AND RowNum > 1
)
UPDATE @TempTable
SET DupCheck = 1
WHERE ItemID IN (SELECT ItemID FROM cteCurDup WHERE RowNum > 1)
【问题讨论】:
-
您能否在
@TempTable中显示一些示例数据以及所需的结果?这通常比逆向工程查询容易得多。 -
对不起,我不能。个人身份信息
-
您当然可以屏蔽 PII。例如,将我的名字改为 Salvadore、Brumsky 或 VitaminWater。您如何生成虚拟数据,或让任何人编写不允许查看 PII 的查询?
-
制作一些虚拟的 FolderID、EntityName、ItemID 来展示需求有多难?这些听起来都不像 PII。
标签: sql sql-server sql-server-2014 common-table-expression