English 中文(简体)
SQL Syntax: Create a single table with column names created from data stored over multiple tables
原标题:

I have created the SQL script below that creates four tables and inserts data into the tables to demonstrate my question (I hope this helps!).

This problem arose because originally this data was stored in a single table of 400 columns and it got very unmanageable so I wanted to find a better way to store the parameters:

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

There are hundreds of parameters in each table (above are just a few) that all references a row from the JobFiles table.

When I run the above SELECT statement I get the following result as expected:

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

What I am trying to achieve is to arrange the data differently to match how the original 400 column table to look like:

Return the data values of the columns named cName, iName, txtName into Columns. Return the data values of the columns named cValue, iValue, txtValue into row data.

i.e.

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

I am not sure how I would go about doing this and would appreciated any advice and help? I have other questions also which I shall post separately.

Thank you in advanced.

最佳回答

I would probably break out the Dept records into their own table, and alter your query accordingly.

The trouble you re running into is because there s no difference between User / Bob and Dept / IT in your current database structure

问题回答

It seems that instead of normalizing your design (1NF, 2NF, 3NF) you have created tables based on data type of each column, and hence pivoted tables with your script.

You can not simply join as if you had logical entities, but have to pivot the whole thing back. Here are some pivoting examples.

I hope you still have the original. I would suggest to normalize your design using entities and relationships, instead of this approach.





相关问题
what is wrong with this mysql code

$db_user="root"; $db_host="localhost"; $db_password="root"; $db_name = "fayer"; $conn = mysqli_connect($db_host,$db_user,$db_password,$db_name) or die ("couldn t connect to server"); // perform query ...

Users asking for denormalized database

I am in the early stages of developing a database-driven system and the largest part of the system revolves around an inheritance type of relationship. There is a parent entity with about 10 columns ...

Easiest way to deal with sample data in Java web apps?

I m writing a Java web app in my free time to learn more about development. I m using the Stripes framework and eventually intend to use hibernate and MySQL For the moment, whilst creating the pages ...

join across databases with nhibernate

I am trying to join two tables that reside in two different databases. Every time, I try to join I get the following error: An association from the table xxx refers to an unmapped class. If the ...

How can I know if such value exists in database? (ADO.NET)

For example, I have a table, and there is a column named Tags . I want to know if value programming exists in this column. How can I do this in ADO.NET? I did this: OleDbCommand cmd = new ...

Convert date to string upon saving a doctrine record

I m trying to migrate one of my PHP projects to Doctrine. I ve never used it before so there are a few things I don t understand. In my current code, I have a class similar to this: class ...

热门标签