sql - 我可以避免在这种递归查找场景中使用游标吗?

标签 sql sql-server t-sql cursor common-table-expression

我有一个名为 Item 的表。设计如下:

ItemTable[
ItemID int,
ItemName varchar(50),
ParentItemId int ]

我想要的是找到所有具有祖先 id 的项目并执行一些操作(例如删除、更新)。

假设我有六件元素,

For Item 1, the parentItemId is null, 
for Item 2, the parentId is 1,
for Item 3, the parentId is 1
Item 4, parent id 2, 
item 5, parent id 2, 
item 6, parent id 4

我想查找祖先 id 为 2 的所有项目。所以应该是 4,5 和 6。

在sql世界中,我可以在游标中完成它。但想知道是否可以使用巧妙的 CTE 来完成某些事情?

最佳答案

您可以使用递归 CTE:

;WITH cte(ItemID, ItemName,ParentItemId) AS (
   SELECT ItemID, ItemName, ParentItemId
   FROM #ItemTable
   WHERE ParentItemId IS NOT NULL
   UNION ALL
   SELECT i.ItemID, i.ItemName, t.ParentItemId
   FROM cte t 
   JOIN #ItemTable i 
     ON t.ItemID = i.ParentItemId
), cte2 AS                -- filter records with Ancestor = 2
(
  SELECT * 
  FROM cte
  WHERE ParentItemId = 2
)
UPDATE #ItemTable          -- UPDATE/DELETE operation
SET ItemName = CONCAT('Updated Name: ', i1.ItemName)
FROM #ItemTable i1
JOIN cte2 c2
  ON i1.ItemID = c2.ItemId;

SELECT *
FROM #ItemTable;

LiveDemo

关于sql - 我可以避免在这种递归查找场景中使用游标吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33923215/

相关文章:

java - android 和 java 中的 SQLite 数据库

c# - 存储在 SQL Server 中时,我的 DateTime 中的毫秒数会发生变化

sql-server - 查找/控制非法数据的方法

SQL 服务器 : setting the value to the next highest id number when the table is not set to auto increment

sql - 排除具有数字字符的行,仅在行的开头

sql - 如何轻松地将列添加到临时表?

sql - 如何从 SQL 表中以逗号分隔值字符串的形式提取 ID 列表?

c# - 是否可以锁定一条记录并仍然允许其他用户读取它?

SQL - STUFF 函数中的 CASE WHEN 作为条件分隔符

mysql - 由于外键,无法在现有列上添加 AUTO_INCREMENT