如何将SQL表解析为多个多对多表

时间:2012-09-02 00:44:34

标签: sql sql-server database-normalization

我有一个Staging表,其中包含以下列

  • VideoURL
  • 评分
  • 长度
  • 缩略图
  • 标签(以逗号分隔)

视频与标签有很多关系。我创建了以下新表:

  • 视频
  • 标签
  • VideoTag

如何将Staging表中的数据解析为三个新表? Tag表不应包含重复项。另外,在将数据插入新表之前,我需要对数据进行一些格式化,例如需要从长度列中删除所有字母。

3 个答案:

答案 0 :(得分:1)

我该怎么做。

  1. 使用此question将CSV列解析为多行,并使用人工键将旧表格链接到新表格
  2. 用另一个生成的人工密钥(多个连接表主键)列连接两个表来创建多个表
  3. 修复多对多关系的两端

答案 1 :(得分:1)

使用辅助数字表,您可以将标记列拆分为行,同时保持与VideoURL关联:

CREATE TABLE NumberPivot (NumberID INT PRIMARY KEY)
DECLARE @intLoopCounter INT
SELECT @intLoopCounter =0
SET NOCOUNT ON

WHILE @intLoopCounter <=999 BEGIN
   INSERT INTO NumberPivot
   VALUES (@intLoopCounter)
   SELECT @intLoopCounter = @intLoopCounter +1
END
GO


SELECT
  ContentPageID,
  Substring(',' + Tags + ','
            , numberID + 1
            , Charindex(',', ',' + Tags + ',', numberID + 1) - numberid - 1) AS value 
FROM   dbo.NumberPivot  AS np,
       Staging AS S
WHERE  numberid <= Len(',' + Tags + ',') - 1
   AND Substring(',' + Tags + ',', numberID, 1) = ',' 

所以我们在这里用唯一标签填充Tags表:

;WITH X AS (
SELECT
  VideoURL,
  Substring(',' + Tags + ',', numberID + 1, Charindex(',', ',' + Tags + ',', numberID + 1) - numberid - 1) AS Tag
FROM   dbo.NumberPivot  AS np,
       Staging AS S
WHERE  numberid                                      <= Len(',' + Tags + ',') - 1
   AND Substring(',' + Tags + ',', numberID, 1) = ',' 
)
INSERT Tag (Tag)
SELECT DISTINCT Tag FROM X;

接下来填写视频表:

INSERT Video (VideoURL, Rating, Length, Thumbnail)
SELECT VideoURL, Rating, Length, Thumbnail
FROM Staging;

最后填写VideoTag:

INSERT VideoTag (VideoURL, Tag)
SELECT
  VideoURL,
  Substring(',' + Tags + ',', numberID + 1, Charindex(',', ',' + Tags + ',', numberID + 1) - numberid - 1) AS Tag
FROM   dbo.NumberPivot  AS np,
       Staging AS S
WHERE  numberid                                      <= Len(',' + Tags + ',') - 1
   AND Substring(',' + Tags + ',', numberID, 1) = ',' 

使用here

中的数字表获得拆分字符串

答案 2 :(得分:1)

尝试此操作,假设videourl为视频名称, splitstring函数 返回表格为 标记名

create table video(...)
create table tag(...)
create table videotag(...)


insert video
select distinct(maintable.videourl) as videoname
from   maintable 


insert tag
select distinct(tag.tagname)
from   maintable cross apply SplitString(maintable.tags,',') tag

insert videotag
select maintable.videourl as videoname,tag.tagname
from   maintable   cross apply SplitString(maintable.tags,',') tag

如果你从视频和标签表中自动生成了ids,那么就是 插入录像带表时,从中获取相关的自动生成的id 这是主表。

Splitstring函数来自here