简体   繁体   中英

SQL Insert new columns in table B from rows of table A

I am using Microsoft SQL Server.

Input

I have a table Horizontal

在此处输入图片说明

and another table Vertical

在此处输入图片说明

Desired output is shown in red.

The aim is that each row of table horizontal is appended as a new column of table vertical.

To be more specific:

  • each row of column 'name' of table Horizontal will be the new column title of appended columns of table Vertical .
  • each row of column 'value' of table Horizontal will be the new appended column rows of table Vertical .

在此处输入图片说明

Thus, I would like to know how to implement the desired result in SQL (I use Microsoft SQL Server).

Code:

CREATE TABLE HORIZONTAL 
(
    id INT NOT NULL  PRIMARY KEY,
    NAME VARCHAR(40) NOT NULL,
    VALUE INT NOT NULL
);

INSERT INTO HORIZONTAL (id, name, value) 
VALUES (1, 'jersey', 22), (2, 'newYork', 33);

CREATE TABLE VERTICAL 
(
    id INT NOT NULL PRIMARY KEY,
    PRODNAME VARCHAR(40) NOT NULL,
);

INSERT INTO VERTICAL (id, prodname) 
VALUES (1, 'apple'), (2, 'orange'), (3, 'kiwi');

You need first to generate each property name for each prod name using cross join, then use the PIVOT operator:

SELECT id, prodname, [jersey], [newyork]
FROM
(
    SELECT
      v.id, name, value, v.prodname
    FROM Horizontal as h
    CROSS JOIN Vertical AS v
) AS t
PIVOT
( 
  MAX(value) for name IN([jersey], [newyork])
) AS p;

Demo

| id | prodname | jersey | newyork |
|----|----------|--------|---------|
|  1 |    apple |     22 |      33 |
|  2 |   orange |     22 |      33 |
|  3 |     kiwi |     22 |      33 |

If you want to do this for any properties and not to list them manually, you need to do it dynamically using dynamic sql like in this demo .

You need a dynamic PIVOT

DECLARE @cols nvarchar(max) = STUFF(
                              (SELECT DISTINCT ',[' + h.name + ']' FROM HORIZONTAL h FOR XML PATH (''))
                             ,1,1,'')
--PRINT @cols

DECLARE @query nvarchar(max) = N'SELECT id, prodname, ' + @cols + char(13) + 
                          N' FROM 
                          (   select v.*, h.name, h.value 
                             from VERTICAL v
                             CROSS JOIN dbo.HORIZONTAL h    
                          ) src
                          PIVOT
                          (
                             MIN(value) FOR name IN ('+ @cols +')
                          ) pvt'

--PRINT @query
EXEC (@query)

See my demo here http://rextester.com/WGUU74996

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM