0

複数の列がある正規化されていないデータベースから新しい正規化されたデータベースにデータをエクスポートする必要があります。 一例として、 30 個のブール列 (ValidSize1、ValidSize2 ecc...) を持つProductsテーブルがあり、すべてのレコードには、サイズ コード (XS、S、M など) を持つ 30 個の列があるSizesテーブルを指す外部キーがあります。 ...)。製品の有効なサイズを取得するには、両方のテーブルをスキャンして、製品の ValidSizeX が true の場合にのみ 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

2 に答える 2

0

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 )
于 2013-02-25T12:15:07.560 に答える
0

さて、「クリーンな」(そしてはるかに高速な) ソリューションはUNPIVOT関数のようです。
ここで非常に良い例を見つけました:

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

于 2013-02-25T14:25:05.717 に答える