Столбец в строки и составьте главную таблицу столбцов - PullRequest
0 голосов
/ 01 февраля 2012

Мне нужно вставить данные столбцов в другую таблицу и создать основную таблицу для столбцов

Как в примере: мне нужно преобразовать таблицу tblcatData в две таблицы tblCat и tblcatDataNew

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    |
    .            .          .
    .            .          .
    .            .          .

Ответы [ 2 ]

3 голосов
/ 01 февраля 2012

Вы можете попробовать следующий сценарий:

  1. Создать tblCat.

  2. Создать tblCatDataNew со следующими отклонениями от исходного дизайна:

    • столбцу FK_CatID разрешено временно принимать значения NULL (или, возможно, навсегда, если это было вашим первоначальным намерением);

    • временно добавлен дополнительный столбец для получения категории имен из исходной таблицы.

  3. Отключить tblCatData и вставить результаты в tblCatDataNew (значения в Data и имена столбцов, как имена категорий, во временный столбец).

  4. Выберите все отдельные имена категорий из tblCatDataNew и вставьте их в tblCat. (Это даст ключевые значения для них.)

  5. Обновите внешние ключи в tblCatDataNew из tblCat, соединив две таблицы по именам категорий.

  6. Удалить временный столбец из tblCatDataNew.

  7. Установите tblCatDataNew.FK_CatID как NOT 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 голосов
/ 01 февраля 2012

Вы можете использовать union для разворачивания столбцов и 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
        ...
        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...