从另一个表中插入类别和子类别

时间:2016-08-03 01:19:13

标签: sql sql-server stored-procedures

我有2个表 - 导入模板,模板表有3个类别。我需要从Import到Template插入类别,但Import只有一列。

sql tables

从图片来看,它应该只插入5个类别,因为有5个不同的类别。有2个sub1类和1个sub2类。模板表中的CSD_ID是自动生成的。 insert语句应使用其父CSD_ID更新Primary_Cat_Id。

示例,厕所是国内的sub2,所以它应该获得国内的CSD_ID并填充在Primary_Cat_Id中,但它也是Bath的sub1,所以它应该获得Bath的CSD_ID并将其填入Parent_ID。

Last_Lev为1或0. 1表示它是最后一级,0表示​​它下面有子类别

1 个答案:

答案 0 :(得分:1)

您可以通过在Template表上创建AFTER INSERT触发器来实现此目的,这样当您从Import表中插入时,它将更新Parent_Id的值,{{1 }},Lev_NoPrimary_Cat_Id会自动生成。

我假设你的表结构看起来像这样:

Last_Lev

您的触发器应如下所示:

IF OBJECT_ID('Import', 'U') IS NOT NULL DROP TABLE Import;

CREATE TABLE Import (
      [Main Category] VARCHAR(255) -- NOT NULL?
    , [Sub Category 1] VARCHAR(255)
    , [Sub Category 2] VARCHAR(255));

INSERT Import 
VALUES ('Domestic', NULL, NULL)
     , ('Domestic', 'House', NULL)
     , ('Domestic', NULL, NULL)
     , ('Domestic', NULL, NULL)
     , ('Domestic', 'Bath', 'Toilet')
     , ('Domestic', NULL, NULL)
     , ('Commercial', NULL, NULL)
     , ('Commercial', NULL, NULL)
     , ('Commercial', NULL, NULL)
     , ('Commercial', NULL, NULL)
     , ('Commercial', NULL, NULL)
     , ('Commercial', NULL, NULL);

IF OBJECT_ID('Template', 'U') IS NOT NULL DROP TABLE Template;

CREATE TABLE Template (
      CSD_ID INT IDENTITY (1, 1) PRIMARY KEY
    , Category VARCHAR(255) NOT NULL
    , Parent_Id INT
    , Lev_No INT
    , Primary_Cat_Id INT
    , Last_Lev BIT);

可能有一种更简单的方法可以做到这一点,但这在技术上有效(至少对于样本数据)。

之后,您只需要一个光标或其他东西来逐个进行插入,从主要类别开始:

IF OBJECT_ID('tr_Template_Insert', 'TR') IS NOT NULL DROP TRIGGER tr_Template_Insert;
GO

CREATE TRIGGER tr_Template_Insert
ON Template
AFTER INSERT
AS BEGIN
    WITH CTE AS (
        SELECT RN, cats, lvl
        FROM (
            SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN 
            FROM Import) T
        CROSS APPLY (
            VALUES ([Main Category], 1)
                 , ([Sub Category 1], 2)
                 , ([Sub Category 2], 3)) S(cats,lvl)
        WHERE S.cats IS NOT NULL
        )
    UPDATE T
    SET Last_Lev = Z.lastLev
        , Primary_Cat_Id = COALESCE(Z.PrimaryCat, T.CSD_ID)
        , Parent_Id = COALESCE(Z.ParentCat, T.CSD_ID)
        , Lev_No = Z.levNo
    FROM Template T
    JOIN (
        SELECT C.cats
             , MAX(CASE WHEN C.lvl = LL.lastlev THEN 1 ELSE 0 END) lastLev
             , MAX(Pri.primarycat) PrimaryCat
             , MAX(Par.parentcat) ParentCat
             , MAX(lvl) levNo
        FROM CTE C
        JOIN inserted I ON I.Category = C.cats
        OUTER APPLY (
            SELECT T.CSD_ID
            FROM CTE CZ
            JOIN Template T ON T.Category = CZ.cats
            WHERE CZ.RN = C.RN
            AND CZ.lvl = 1) Pri(primarycat)
        OUTER APPLY (
            SELECT T.CSD_ID
            FROM CTE CZ
            JOIN Template T ON T.Category = CZ.cats
            WHERE CZ.RN = C.RN
            AND CZ.lvl = C.lvl-1) Par(parentcat)
        OUTER APPLY (
            SELECT MAX(lvl)
            FROM CTE CZ
            WHERE CZ.RN = C.RN) LL(lastlev)
        GROUP BY C.cats) Z ON Z.cats = T.Category;
END

光标将插入主类别,然后是子类别1,然后是子类别2,触发器将填充其余值。