2012-02-01 25 views
0

我需要插入列数据不同的表,并创建列主表列到行,使列的主表

就像例如:我需要转换表tblcatData成两个表tblCattblcatDataNew

tblCatData

Primaykey | A | B | C | D | D | F | G | H | I | J | K | L | M | 
-------------------------------------------------------------------- 
    1   | 1 | 2 | 3 | 5 | 5 | 5 | 3 | 3 | 3 | 1 | 4 | 1 | 1 | 
    2   | 1 | 2 | 5 | 5 | 5 | 5 | 3 | 5 | 3 | 1 | 1 | 5 | 1 | 
    3   | 5 | 2 | 3 | 5 | 5 | 5 | 5 | 3 | 3 | 1 | 1 | 1 | 4 | 

tblCat

PrimaryKey | Category 
---------------------------- 
    1   | A 
    2   | B 
    3   | C 
    4   | D 
    5   | E 
    6   | F 
    7   | G 
    .   . 
    .   . 
    .   . 

tblCatDataNew

PrimaryKey | FK_CatID | Data | 
----------------------------------- 
    1   | 1  | 1 | 
    2   | 1  | 1 | 
    3   | 1  | 5 | 
    4   | 2  | 2 | 
    5   | 2  | 2 | 
    6   | 2  | 2 | 
    7   | 3  | 3 | 
    8   | 3  | 5 | 
    .   .   . 
    .   .   . 
    .   .   . 

回答

3

你可以请尝试以下方案:

  1. 创建tblCat

  2. 创建tblCatDataNew从最初的设计以下不同之处:

    • FK_CatID列允许暂时接受空值(或者永久地,如果这是你的初衷);

    • 临时添加一个额外列以从原始表中接收名称名称

  3. 逆透视tblCatData和结果插入tblCatDataNew(该值到Data和列名,如类别名称,到临时列)。

  4. tblCatDataNew中选择所有不同的类别名称并将它们插入tblCat。 (这将产生它们的关键值。)

  5. 更新tblCatDataNew中的外键从tblCat,按类别名称连接两个表。

  6. 将临时列从tblCatDataNew中删除。

  7. 设置为tblCatDataNew.FK_CatIDNOT NULL(也就是说,如果你想这样做)。

这里就是整个测试脚本,包括创建原始表的(如果有人想尝试一下):

BEGIN TRANSACTION 
GO 

/* prepare the original table, for tests */ 
WITH data (
    Primaykey, A, B, C, D, E, F, G, H, I, J, K, L, M 
) AS (
    SELECT 1 , 1, 2, 3, 5, 5, 5, 3, 3, 3, 1, 4, 1, 1 UNION ALL 
    SELECT 2 , 1, 2, 5, 5, 5, 5, 3, 5, 3, 1, 1, 5, 1 UNION ALL 
    SELECT 3 , 5, 2, 3, 5, 5, 5, 5, 3, 3, 1, 1, 1, 4 
) 
SELECT * INTO tblCatData FROM data; 
GO 

/* Step 1 */ 
CREATE TABLE tblCat (
    PrimaryKey int IDENTITY CONSTRAINT PK_tblCat PRIMARY KEY, 
    Category varchar(50) NOT NULL 
); 
GO 

/* Step 2 */ 
CREATE TABLE tblCatDataNew (
    PrimaryKey int IDENTITY CONSTRAINT PK_tblCatDataNew PRIMARY KEY, 
    FK_CatID int NULL CONSTRAINT FK_tblCatDataNew_tblCat FOREIGN KEY REFERENCES tblCat (PrimaryKey), 
    Data int, 
    Category varchar(50) 
); 
GO 

/* Step 3 */ 
INSERT INTO tblCatDataNew (
    Data, 
    Category 
) 
SELECT 
    Data, 
    Category 
FROM tblCatData 
UNPIVOT (
    Data for Category IN (A, B, C, D, E, F, G, H, I, J, K, L, M) 
) u 
ORDER BY 
    Category, 
    Primaykey; 
GO 

/* Step 4 */ 
INSERT INTO tblCat (Category) 
SELECT DISTINCT Category 
FROM tblCatDataNew 
GO 

/* Step 5 */ 
UPDATE tblCatDataNew 
SET FK_CatID = c.PrimaryKey 
FROM tblCat c 
WHERE tblCatDataNew.Category = c.Category 

GO 

/* Step 6 */ 
ALTER TABLE tblCatDataNew 
DROP COLUMN Category 
GO 

/* Step 7 */ 
ALTER TABLE tblCatDataNew 
ALTER COLUMN FK_CatID int NOT NULL 
GO 

/* view the results */ 
SELECT * FROM tblCat 
SELECT * FROM tblCatDataNew 
GO 

ROLLBACK TRANSACTION 

注意,UNPIVOT子句中的SQL Server支持从开始2005版。在早期版本中,您必须使用不同的方法来反转数据(步骤3),例如像这样:

INSERT INTO tblCatDataNew (
    Data, 
    Category 
) 
SELECT 
    Data = CASE x.CatNum 
    WHEN 1 THEN A 
    WHEN 2 THEN B 
    WHEN 3 THEN C 
    WHEN 4 THEN D 
    WHEN 5 THEN E 
    WHEN 6 THEN F 
    WHEN 7 THEN G 
    WHEN 8 THEN H 
    WHEN 9 THEN I 
    WHEN 10 THEN J 
    WHEN 11 THEN K 
    WHEN 12 THEN L 
    WHEN 13 THEN M 
    END, 
    Category = CASE x.CatNum 
    WHEN 1 THEN 'A' 
    WHEN 2 THEN 'B' 
    WHEN 3 THEN 'C' 
    WHEN 4 THEN 'D' 
    WHEN 5 THEN 'E' 
    WHEN 6 THEN 'F' 
    WHEN 7 THEN 'G' 
    WHEN 8 THEN 'H' 
    WHEN 9 THEN 'I' 
    WHEN 10 THEN 'J' 
    WHEN 11 THEN 'K' 
    WHEN 12 THEN 'L' 
    WHEN 13 THEN 'M' 
    END 
FROM tblCatData 
    CROSS JOIN (
    SELECT 1 UNION ALL 
    SELECT 2 UNION ALL 
    SELECT 3 UNION ALL 
    SELECT 4 UNION ALL 
    SELECT 5 UNION ALL 
    SELECT 6 UNION ALL 
    SELECT 7 UNION ALL 
    SELECT 8 UNION ALL 
    SELECT 9 UNION ALL 
    SELECT 10 UNION ALL 
    SELECT 11 UNION ALL 
    SELECT 12 UNION ALL 
    SELECT 13 
) x (CatNum) 
ORDER BY 
    Category, 
    Primaykey; 

,甚至是这样的:

INSERT INTO tblCatDataNew (
    Data, 
    Category 
) 
SELECT 
    Data = CASE x.CatNum 
    WHEN 1 THEN A 
    WHEN 2 THEN B 
    WHEN 3 THEN C 
    WHEN 4 THEN D 
    WHEN 5 THEN E 
    WHEN 6 THEN F 
    WHEN 7 THEN G 
    WHEN 8 THEN H 
    WHEN 9 THEN I 
    WHEN 10 THEN J 
    WHEN 11 THEN K 
    WHEN 12 THEN L 
    WHEN 13 THEN M 
    END, 
    Category = x.CatName 
FROM tblCatData 
    CROSS JOIN (
    SELECT 1, 'A' UNION ALL 
    SELECT 2, 'B' UNION ALL 
    SELECT 3, 'C' UNION ALL 
    SELECT 4, 'D' UNION ALL 
    SELECT 5, 'E' UNION ALL 
    SELECT 6, 'F' UNION ALL 
    SELECT 7, 'G' UNION ALL 
    SELECT 8, 'H' UNION ALL 
    SELECT 9, 'I' UNION ALL 
    SELECT 10, 'J' UNION ALL 
    SELECT 11, 'K' UNION ALL 
    SELECT 12, 'L' UNION ALL 
    SELECT 13, 'M' 
) x (CatNum, CatName) 
ORDER BY 
    Category, 
    Primaykey; 

下面是结果,上面的脚本我制作:

  • tblCat

    PrimaryKey Category 
    ----------- -------------------------------------------------- 
    1   A 
    2   B 
    3   C 
    4   D 
    5   E 
    6   F 
    7   G 
    8   H 
    9   I 
    10   J 
    11   K 
    12   L 
    13   M 
    
  • tblCatDataNew

    PrimaryKey FK_CatID Data 
    ----------- ----------- ----------- 
    1   1   1 
    2   1   1 
    3   1   5 
    4   2   2 
    5   2   2 
    6   2   2 
    7   3   3 
    8   3   5 
    9   3   3 
    10   4   5 
    11   4   5 
    12   4   5 
    13   5   5 
    14   5   5 
    15   5   5 
    16   6   5 
    17   6   5 
    18   6   5 
    19   7   3 
    20   7   3 
    21   7   5 
    22   8   3 
    23   8   5 
    24   8   3 
    25   9   3 
    26   9   3 
    27   9   3 
    28   10   1 
    29   10   1 
    30   10   1 
    31   11   4 
    32   11   1 
    33   11   1 
    34   12   1 
    35   12   5 
    36   12   1 
    37   13   1 
    38   13   1 
    39   13   4 
    
0

您可以使用union到UNPIVOT列,select ... into存储结果在一个新表:

select PrimaryKey 
,  FK_CatId 
,  Category 
into tblCatDataNew 
from (
     select PrimaryKey 
     ,  1 
     ,  A 
     from tblCatData 
     union all 
     select PrimaryKey 
     ,  2 
     ,  B 
     from tblCatData 
     union all 
     ... 
     )