【问题标题】:How to parse SQL table into multiple many-to-many tables如何将 SQL 表解析为多个多对多表
【发布时间】:2012-09-02 11:16:23
【问题描述】:

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

  • 视频网址
  • 评分
  • 长度
  • 缩略图
  • 标签(逗号分隔)

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

  • 视频
  • 标签
  • 视频标签

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

【问题讨论】:

  • 我很困惑,请澄清 - 这纯粹是在 SQL 中吗?在这种情况下,您应该删除 ef 和 c# 标签。
  • 糟糕,忘记脱掉了。实际上,我对 SQL 或实体框架解决方案都感兴趣,但认为 EF 最终无法接近直接 SQL 的性能。

标签: sql sql-server database-normalization


【解决方案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) = ',' 

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

;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. 使用此question 将 CSV 列解析为多行,另一个表使用人工键将旧表链接到新表
    2. 使用另一个生成的人工键(Many many join table primary key)列连接两个表以创建多对多表
    3. 修复多对多关系的两端

    【讨论】:

      【解决方案3】:

      试试这个,假设 videourl 作为视频名称并且 splitstring function 返回表有 tagname

      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
      

      如果您从视频和标签表中自动生成 ID,那么
      在插入 videotag 表时,从
      获取关联的自动生成的 id 这是主表。

      拆分字符串函数来自here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-04
        • 2021-08-21
        • 2017-05-06
        • 2023-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多