Синтаксис SQL: создать одну таблицу с именами столбцов, созданными из данных, хранящихся в нескольких таблицах - PullRequest
1 голос
/ 18 ноября 2009

Я создал приведенный ниже скрипт SQL, который создает четыре таблицы и вставляет данные в таблицы, чтобы продемонстрировать мой вопрос (надеюсь, это поможет!).

Эта проблема возникла из-за того, что изначально эти данные хранились в одной таблице из 400 столбцов и стали очень неуправляемыми, поэтому я хотел найти лучший способ хранения параметров:

use master
GO
create database sptest
go

use sptest
go

CREATE TABLE JobFiles (
            [Id]       int PRIMARY KEY IDENTITY(0,1),
   [JobName]       nvarchar(256)  DEFAULT '',
   [CreateDate]     DateTime NOT NULL DEFAULT GETDATE(),
   [ModifyDate]     DateTime NOT NULL DEFAULT GETDATE(),
   [CreatedByUser]     nvarchar(64)  DEFAULT '',
   [ModifiedByUser]    nvarchar(64)  DEFAULT '')
GO


CREATE TABLE jpChar (
  [jpId] int PRIMARY KEY IDENTITY(0,1),
  [JobId] int REFERENCES JobFiles(Id),
  [jpName] varchar(64),
  [jpValue] nvarchar(255))


CREATE TABLE jpInt (
  [jpId] int PRIMARY KEY IDENTITY(0,1),
  [JobId] int REFERENCES JobFiles(Id),
  [jpName] varchar(64),
  [jpValue] int)

CREATE TABLE jpText (
  [jpId] int PRIMARY KEY IDENTITY(0,1),
  [JobId] int REFERENCES JobFiles(Id),
  [jpName] varchar(64),
  [jpValue] Text)


use spTest
go

    INSERT INTO JobFiles(JobName) VALUES ('File0')
    INSERT INTO JobFiles(JobName) VALUES ('File1')
    INSERT INTO JobFiles(JobName) VALUES ('File2')

    INSERT INTO jpChar(JobId,jpName, jpValue) VALUES (0, 'User', 'Paul')
    INSERT INTO jpChar(JobId,jpName, jpValue) VALUES (0, 'Dept', 'IT')
    INSERT INTO jpInt (JobId,jpName, jpValue) VALUES (0, 'Hours', '40')
    INSERT INTO jpText (JobId,jpName, jpValue) VALUES (0, 'Notes', 'Some Text')


    INSERT INTO jpChar(JobId,jpName, jpValue) VALUES (1, 'User', 'Bob')
    INSERT INTO jpChar(JobId,jpName, jpValue) VALUES (1, 'Dept', 'Sales')
    INSERT INTO jpInt (JobId,jpName, jpValue) VALUES (1, 'Hours', '20')
    INSERT INTO jpText (JobId,jpName, jpValue) VALUES (1, 'Notes', 'Some more Text')


    INSERT INTO jpChar(JobId,jpName, jpValue) VALUES (2, 'User', 'Jane')
    INSERT INTO jpChar(JobId,jpName, jpValue) VALUES (2, 'Dept', 'Support')


SELECT  JobFiles.Id, JobFiles.JobName,   
   jpChar.jpName AS cName, jpChar.jpValue AS cValue,
   jpInt.jpName AS iName, jpInt.jpValue AS iValue,
   jpText.jpName AS txtName, jpText.jpValue AS txtValue
FROM         JobFiles INNER JOIN
                      jpChar ON JobFiles.Id = jpChar.JobId LEFT JOIN
                      jpInt ON JobFiles.Id = jpInt.JobId LEFT JOIN
                      jpText ON JobFiles.Id = jpText.JobId

Есть сотни параметров в каждой таблице (выше только несколько), которые все ссылаются на строку из таблицы JobFiles.

Когда я запускаю приведенную выше инструкцию SELECT, я получаю следующий результат, как и ожидалось:

id  JobName cName   cValue  iName   iValue  txtName txtValue
0   File0   User    Paul    Hours   40      Notes   Some Text
0   File0   Dept    IT      Hours   40      Notes   Some Text
1   File1   User    Bob     Hours   20      Notes   Some more Text
1   File1   Dept    Sales   Hours   20      Notes   Some more Text
2   File2   User    Jane    NULL    NULL    NULL    NULL
2   File2   Dept    Support NULL    NULL    NULL    NULL

Я пытаюсь добиться того, чтобы данные располагались по-разному, чтобы они выглядели так, как выглядит исходная таблица из 400 столбцов:

Возвращает значения данных столбцов с именами cName, iName, txtName в столбцы. Вернуть значения данных столбцов с именами cValue, iValue, txtValue в данные строки.

т.е.

id  JobName User   Dept    Hours   Notes
0   File0   Paul   IT      40      Some Text
1   File1   Bob    Sales   20      Some more Text 
2   File2   Jane   Support NULL    NULL
.     .       .       .      .       .

Я не уверен, как бы я поступил так и был бы признателен за любые советы и помощь? У меня есть и другие вопросы, которые я опубликую отдельно.

Спасибо заранее.

Ответы [ 2 ]

1 голос
/ 18 ноября 2009

Похоже, что вместо нормализации вашего проекта (1NF, 2NF, 3NF) вы создали таблицы на основе типа данных каждого столбца и, следовательно, сводные таблицы с вашим сценарием.

Вы не можете просто присоединиться, как если бы у вас были логические объекты, но вы должны повернуть все обратно. Вот несколько поворотных примеров .

Надеюсь, у вас еще есть оригинал. Я бы предложил нормализовать ваш дизайн, используя сущности и отношения вместо этого подхода.

1 голос
/ 18 ноября 2009

Я бы, вероятно, разбил записи 'Dept' на их собственную таблицу и изменил бы ваш запрос соответствующим образом.

Проблема, с которой вы сталкиваетесь, заключается в том, что нет никакой разницы между 'User' / 'Bob' и 'Dept' / 'IT' в вашей текущей структуре базы данных

...