使用一些父子数据创建字符串并将其与列匹配

时间:2014-11-05 13:17:25

标签: sql sql-server sql-server-2008

我有两张表格如下:

CREATE TABLE table1
  (
     id      INT PRIMARY KEY,
     parent1 INT,
     parent2 INT,
     RKey    VARCHAR(max)
  )

CREATE TABLE table2
  (
     id   INT PRIMARY KEY,
     RKey VARCHAR(max)
  ) 

这两个表之间的关系是table1.parent2 = table2.id。 Table1.parent1用于维护递归关系,table1.RKey的计算如下图所示: Example hierarchy 但是,有一些错误的RKey记录,见下面是一些示例数据:

insert into table1 (id,parent1,parent2,RKey) 
values
--hierarchy 1
(5010,NULL,1004,'1002.1004.5010'),              --level 1
(5011,5010,1004,'1002.1004.5010.5011'),         --level 2
(5012,5010,1004,'1002.1004.5010.5012'),         --level 2
--hierarchy 2
(5020,NULL,1005,'1002.1005.5020'),              --level 1
(5021,5020,1005,'1002.1005.5020.5021'),         --level 2
(5022,5021,1005,'1002.1005.5020.5021.5022'),    --level 3
(5023,5021,1005,'1002.1005.5020.5021.5023'),    --level 3
--hierarchy 3
(5030,NULL,1004,'1002.1004.5030'),              --level 1
(5031,5030,1004,'1002.1004.50301.5031'),        --level 2
(5032,5030,1004,'1002.1004.50301.5032'),        --level 2
--hierarchy 4
(5040,NULL,1004,'1002.1004.50401'),             --level 1
(5041,5040,1004,'1002.1004.50401.50411'),       --level 2
(5042,5041,1004,'1002.1004.50401.50411.5042'),  --level 3
(5043,5041,1004,'1002.1004.50401.50411.5043')   --level 3

--parent2 will be same in a hierarchy.

insert into table2 (id,RKey) 
values
(1004,'1002.1004'),
(1005,'1002.1005')

层次结构1和2中的RKey是正确的但如果您看到层次结构3和4,则RKey是错误的。现在,我想返回这样的记录,查询/查询的Rkey不正确,另外一列显示正确的Rkey。 Here是一个SQL小提琴,包含示例数据和我迄今为止所尝试过的内容。

预期结果:

id      WrongRKey                           CorrectRKry
----    ----                                ----                    
5031    1002.1004.50301.5031                1002.1004.5030.5031     
5032    1002.1004.50301.5032                1002.1004.5030.5032     
5040    1002.1004.50401                     1002.1004.5040          
5041    1002.1004.50401.50411               1002.1004.5040.5041     
5042    1002.1004.50401.50411.5042          1002.1004.5040.5041.5042
5043    1002.1004.50401.50411.5043          1002.1004.5040.5041.5043

由于

2 个答案:

答案 0 :(得分:1)

您的加入不正确。

在CTE更正的sql语句下面,我还包含了一个更新连接语句,请记住CTE只是"一次拍摄",see this post

这是Fiddle

with cte (Id, WrongRKey, CorrectRKey)
as
(
select    
       b.id
      ,b.RKey 
      ,c.RKey + '.' +
      case when a.parent1 is null then '' else cast(a.parent1 as varchar) + '.' end +
      case when b.parent1 is null then '' else cast(b.parent1 as varchar) + '.' end +
      case when b.id is null then '' else cast(b.id as varchar)  end 
from table1 a 
        right join table1 b
     on a.id = b.parent1
        inner join table2 c
     on a.parent2 = c.id or b.parent2 = c.id
)

--update
--  tb1
--SET RKEY = ct.CorrectRKey
--from 
--    table1 tb1 
--      inner join cte ct 
--  on tb1.id = ct.id


select *
from cte 
where WrongRKey <> CorrectRKey

我的建议是在这里使用名为层次结构ID的内置数据类型MSDN link来获取此类型数据。

答案 1 :(得分:0)

我找到了CTE的另一种方法,我认为它比多次连接相同的表更好:

;WITH cte
     AS (SELECT id,
                parent1,
                parent2,
                RKey,
                Cast(id AS VARCHAR(300)) AS ComputedRKey
         FROM   table1
         WHERE  parent1 IS NULL
         UNION ALL
         SELECT p.id,
                p.parent1,
                c.parent2,
                p.RKey,
                Cast(c.ComputedRKey + '.'
                     + Cast(p.id AS VARCHAR(10)) AS VARCHAR(300)) AS ComputedRKey
         FROM   table1 p
                JOIN cte c
                  ON p.parent1 = c.id)
SELECT c.id,
       c.RKey                            AS WrongKey,
       ( p.RKey + '.' + c.ComputedRKey ) AS CorrectRKey
FROM   cte c
       LEFT OUTER JOIN table2 p WITH(nolock)
                    ON c.parent2 = p.id 
WHERE  c.RKey <> ( p.RKey + '.' + c.ComputedRKey )