【问题标题】:Export data from a non-normalized database从非规范化数据库中导出数据
【发布时间】:2021-06-14 13:09:39
【问题描述】:

我需要将数据从非规范化数据库(其中有多列)导出到新的规范化数据库。
一个例子是 Products 表,它有 30 个布尔列(ValidSize1、ValidSize2 ecc...),每条记录都有一个外键指向一个 Sizes 表,其中是 30 列,带有尺寸代码(XS、S、M 等...)。为了获取产品的有效尺寸,我必须扫描两个表并仅在产品上的 ValidSizeX 为真时从 Sizes 表中获取值 SizeCodeX。像这样的:

Products Table
--------------
ProductCode <PK>
Description
SizesTableCode <FK>
ValidSize1
ValidSize2
[...]
ValidSize30

Sizes Table
-----------
SizesTableCode <PK>
SizeCode1
SizeCode2
[...]
SizeCode30

现在我正在使用重复 30 次的“模板”查询:

SELECT
    Products.Code,
    Sizes.SizesTableCode, -- I need this code because different codes can have same size codes
    Sizes.Size_1
FROM Products
INNER JOIN Sizes
ON Sizes.SizesTableCode = Products.SizesTableCode
WHERE Sizes.Size_1 IS NOT NULL
AND Products.ValidSize_1 = 1

我只是将这个查询放在一个循环中,并将“_1”替换为循环索引:

SET @counter = 1;
SET @max     = 30;
SET @sql     = '';

WHILE (@counter <= @max)
BEGIN
    SET @sql = @sql + ('[...]'); -- Here goes my query with dynamic indexes

    IF @counter < @max
        SET @sql = @sql + ' UNION ';
    
    SET @counter = @counter + 1;
END

INSERT INTO DestDb.ProductsSizes EXEC(@sql); -- Insert statement
GO

有没有更好、更清洁或更快的方法来做到这一点?我正在使用 SQL Server,我只能使用 SQL/TSQL

【问题讨论】:

  • 您的模板查询中有一个恶意逗号(第 4 行末尾)。

标签: sql sql-server database export


【解决方案1】:

您可以使用 SYS.Syscolumns 表准备动态查询以获取行中的所有值

DECLARE @SqlStmt                 Varchar(MAX)
 SET @SqlStmt=''
 SELECT @SqlStmt = @SqlStmt + 'SELECT '''+ name +''' column ,  UNION ALL ' 
 FROM SYS.Syscolumns WITH (READUNCOMMITTED)
 WHERE Object_Id('dbo.Products')=Id AND ([Name] like 'SizeCode%' OR [Name] like  'ProductCode%')

  IF REVERSE(@SqlStmt) LIKE REVERSE('UNION ALL ') + '%'
    SET @SqlStmt = LEFT(@SqlStmt, LEN(@SqlStmt) - LEN('UNION ALL '))

   print ( @SqlStmt )

【讨论】:

  • 我刚刚找到了一个不使用动态SQL的解决方案,而且速度非常快!
【解决方案2】:

好吧,看起来“干净”(而且速度更快!)的解决方案是UNPIVOT 函数。
我在这里找到了一个很好的例子:

http://pratchev.blogspot.it/2009/02/unpivoting-multiple-columns.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-23
    • 2013-01-18
    • 1970-01-01
    • 2012-11-18
    • 2016-11-18
    • 2010-09-17
    • 1970-01-01
    • 2017-01-14
    相关资源
    最近更新 更多