【问题标题】:SQL: Find missing hierarchy element linksSQL:查找缺少的层次结构元素链接
【发布时间】:2014-08-27 03:52:49
【问题描述】:

我有一个系统,其中包括关键字的父子表(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,因此层次结构不完整。我需要识别父级未链接的那些记录并插入适当的记录。

【问题讨论】:

  • 如果您有示例数据和预期输出,这将更容易可视化和回答。 SQLFiddle 将是额外的奖励。

标签: sql sql-server parent-child


【解决方案1】:

数据导入时:

  1. 对于每个关键字,判断它是否存在于keywords表中,如果不存在则定义为父代(即parentID = NULL)

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

删除表 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) 选择父子关键字并插入到Links表中

【讨论】:

  • 我不确定这个解决方案是否有效 - 缺少的层次结构元素不在关键字表中,而是在链接表中。
  • 我使用了一个变体结合三个嵌套循环来填充链接表。
猜你喜欢
  • 2013-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多