安全地删除相同的引用多列行?

时间:2018-04-04 22:53:55

标签: sql sql-server

我需要找到所有父子关系,这些关系都链接到我的主要列ID

如何删除表中的相同参考列?比如说,如果我想删除“Google”,我必须删除“HP”,而Intel也首先也是HP的孩子。

enter image description here

enter image description here

到目前为止,我已尝试过以下内容,但只能使用一列。

    WITH tb  (id,Name, Level, Path, Parent)
AS
(
 SELECT 
    id,Name, 1 AS Level, 
    CAST('/'+Name as nvarchar(max)) as Path,
    CAST(NULL as nvarchar(max)) as Parent
 FROM krishtest
 WHERE parent1 IS NULL

 UNION All

 SELECT 
    e.id,e.Name, x.Level + 1 AS Level, x.Path + '/' + e.Name as Path,
    REVERSE(SUBSTRING( REVERSE(x.[Path]) ,0 , CHARINDEX( '/', REVERSE(x.[Path])) )) as [Parent]
 FROM krishtest e
 JOIN tb x ON x.id = e.parent1


)
SELECT Name, Level, Path, Parent FROM tb

3 个答案:

答案 0 :(得分:0)

我还没有在这里为您的问题提供实际的解决方案。但我建议调查递归公用表表达式。这应该允许您查找所有父记录,然后您可以对它们运行删除。

https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx

答案 1 :(得分:0)

这个用途是否充分?

declare @tmp table (id int, Name varchar(10),Parent1 int,Parent2 int,Parent3 int,Parent4 int,Parent5 int)


insert into @tmp
SELECT 1,'Microsoft',NULL,NULL,NULL,NULL,NULL
union
SELECT 2,'Google',1,NULL,NULL,NULL,NULL
union
SELECT 3,'HP',NULL,2,NULL,NULL,NULL
union
SELECT 4,'Amazone',NULL,NULL,3,NULL,NULL
union
SELECT 5,'FB',NULL,NULL,NULL,4,NULL
 union
SELECT 6,'Yahoo',NULL,NULL,NULL,4,NULL
 union
SELECT 7,'Intel',NULL,NULL,2,NULL,NULL
union
SELECT 8,'Apple',7,5,NULL,NULL,NULL


select * from @tmp

;with name_tree as (
   select *
   from @tmp
   where id = 2 
   union all
   select c.*
   from @tmp c
     join name_tree p on (p.id = c.parent1 or p.id = c.parent2 or p.id = c.parent3 or p.id = c.parent4 or p.id = c.parent5)
) 


delete from t
from @tmp t
JOIN name_tree c on t.id=c.id

select * from @tmp

答案 2 :(得分:0)

您可以简单地修改递归CTE的where子句,如下面的查询,以获取所有需要删除的行。

See live demo

create table  krishtest (id int, name varchar(100), parent1  int, parent2  int)
insert into krishtest values
(1,'Microsoft', NULL, NULL),
(2,'Google',1,NULL),
(3,'HP',NULL,2),
(4,'amazon',3,NULL),
(5,'FB',NULL,4),
(6,'yahoo',3,NULL),
(7,'cisco',6,NULL)



;
WITH tb  (id,Name, Level, Path, Parent)
AS
(
 SELECT 
    id,Name, 1 AS Level, 
    CAST('/'+Name as nvarchar(max)) as Path,
    CAST(NULL as nvarchar(max)) as Parent
 FROM krishtest
 WHERE -- COALESCE(parent1,parent2) IS NULL
    name ='HP'

 UNION All

 SELECT 
    e.id,e.Name, x.Level + 1 AS Level, x.Path + '/' + e.Name as Path,
    REVERSE(SUBSTRING( REVERSE(x.[Path]) ,0 , CHARINDEX( '/', REVERSE(x.[Path])) )) as [Parent]
 FROM krishtest e
 JOIN tb x ON x.id = COALESCE(e.parent1,e.parent2)


)


   --delete FROM krishtest where id in( select id from tb)
   --select * from krishtest
   SELECT Name, Level, Path, Parent FROM tb