如何通过从列中将逗号分隔的文本提取到子表中来规范化表?

时间:2016-05-15 12:06:51

标签: sql-server

我有一个包含空格和逗号分隔符的定义的表。这些定义看起来像“猫,狗,马,房子,城市”。在逗号之前或之后可以出现空格。

CREATE TABLE [dbo].[WordForm] 
(
    [WordFormId]       VARCHAR (20)  NOT NULL,
    [WordFormIdentity] INT           IDENTITY (1, 1) NOT NULL,
    [WordId]           VARCHAR (20)  NOT NULL,
    [Definition]       VARCHAR (MAX) NULL,

    PRIMARY KEY CLUSTERED ([WordFormId] ASC),

    CONSTRAINT [FK_WordFormPos] 
        FOREIGN KEY ([PosId]) REFERENCES [dbo].[Pos] ([PosId]),
    CONSTRAINT [FK_WordFormWord] 
        FOREIGN KEY ([WordId]) REFERENCES [dbo].[Word] ([WordId])
);

我想删除“定义”列,并将其替换为每行有一个定义的表:

CREATE TABLE [dbo].[Definition]
(
    [DefinitionId] INT IDENTITY (1, 1) NOT NULL,
    [WordFormId] VARCHAR (20) NOT NULL,
    [Text] VARCHAR (30) NOT NULL,

    PRIMARY KEY CLUSTERED ([SynonymId] ASC),

    CONSTRAINT [FK_DefinitionWordForm] 
        FOREIGN KEY ([WordFormId]) REFERENCES [dbo].[WordForm] ([WordFormId])
);

有人可以建议我如何从Definition列中取出数据并将其插入新Definition表中行的文本列中吗?希望检查Definition的解决方案不是空的。

谢谢。

1 个答案:

答案 0 :(得分:3)

您可以使用以下查询拆分逗号分隔列表,并为列表中的每个定义值获取一行。

Select [WordFormId]
     ,RTRIM(LTRIM([Definition])) [Definition]
from 
(
SELECT t.[WordFormId] 
          ,Split.a.value('.', 'VARCHAR(100)') [Definition]
FROM   
    (SELECT [WordFormId]
            ,Cast ('<X>' + Replace([Definition], ',', '</X><X>') + '</X>' AS XML) AS Data
     FROM    [dbo].[WordForm]
    ) AS t CROSS APPLY Data.nodes ('/X') AS Split(a)
 )a 

我还使用LTRIM()RTRIM()函数来删除任何空格。