SQL:查找缺少的层次结构元素链接

时间:2014-08-27 03:52:49

标签: sql sql-server parent-child

我有一个系统,其中包括一个关键字的父子表(cols:ID | Keyword | ParentID),一个事件表和一个将关键字链接到事件的表(cols:EventID | KeywordID)。

当一个关键字被添加到一个事件时,UI中的业务逻辑将为所选关键字的链接表添加一个条目,以及该关键字具有的任何父级,因此该层次结构的第三级的关键字将产生链接表中的三个条目。

在某些情况下,导入的数据只包含链接的关键字,这些关键字可以位于父子表中定义的层次结构中的任何级别。也就是说,只有一条记录被添加到链接表中。

是否存在仅使用SQL查询(无存储过程)的方法,这将允许识别未链接的层次结构元素并将相应的记录插入到链接表中?

来自SQLFiddle(http://sqlfiddle.com/#!6/c13c5)的示例表:

CREATE TABLE Keywords
    ([ID] int, [Keyword] varchar(9), [ParentID] varchar(4))
;

INSERT INTO Keywords
    ([ID], [Keyword], [ParentID])
VALUES
    (1, 'Keyword 1', NULL),
    (2, 'Keyword 2', '1'),
    (3, 'Keyword 3', '1'),
    (4, 'Keyword 4', '2'),
    (5, 'Keyword 5', '3')
;




CREATE TABLE Events
    ([ID] int, [Description] varchar(4))
;

INSERT INTO Events
    ([ID], [Description])
VALUES
    (1, 'Foo'),
    (2, 'Bar'),
    (3, 'Foo2'),
    (4, 'Foo3')
;



CREATE TABLE EventKeywordLink
    ([Event ID] int, [Keyword ID] int)
;

INSERT INTO EventKeywordLink
    ([Event ID], [Keyword ID])
VALUES
    (1, 2),
    (2, 2),
    (2, 3)
;

注意,事件2与关键字2& 3,但不是1,因此层次结构不完整。我需要识别父链接取消链接的那些记录并插入适当的记录。

1 个答案:

答案 0 :(得分:0)

导入数据时:

  1. 对于每个关键字,确定它是否存在于关键字表中,如果没有将其定义为父关键字(即,parentID = NULL)

  2. 如果关键字确实存在,请确定最顶层的父级。这可以通过递归CTE来完成。

  3. DROP TABLE temp.dbo。#keywords

    CREATE TABLE #keywords 
      ( 
         keywordid INT, 
         parentid  INT, 
         keyword   VARCHAR(100) 
      ) 
    
    INSERT INTO #keywords 
    VALUES      (1, 
                 NULL, 
                 'test') 
    
    INSERT INTO #keywords 
    VALUES      (2, 
                 1, 
                 'test_lower') 
    
    INSERT INTO #keywords 
    VALUES      (3, 
                 1, 
                 'test_upper'); 
    
    INSERT INTO #keywords 
    VALUES      (4, 
                 2, 
                 'test_side'); 
    
    go 
    
    WITH c ( parentid) 
         AS (SELECT parentid 
             FROM   #keywords 
             WHERE  keyword = 'test_lower' 
             UNION ALL 
             SELECT k.parentid 
             FROM   #keywords k 
                    JOIN c 
                      ON k.keywordid = c.parentid 
             WHERE  k.keywordid <> k.parentid) 
    SELECT parentid 'topmost' 
    FROM   c 
    

    3)选择父子关键字并插入到链接表

相关问题