如何将表的前两列堆叠到单个列中,还将第三列与第一列对齐?

时间:2018-03-02 14:00:48

标签: sql sql-server tsql unpivot

我之前问了similar question,但这次的要求有点复杂。我有一个如下所示的表:

| id | code_1 | code_2 | pair_1 |
|----|--------|--------|--------|
|  1 |     a1 |     a2 |     b1 |
|  2 |     a3 |     a4 | (null) |
|  3 |     a5 | (null) |     b2 |
|  4 |     a6 | (null) | (null) |
|  5 | (null) |     a7 |     b3 |
|  6 | (null) |     a8 | (null) |
|  7 | (null) | (null) |     b4 |
|  8 | (null) | (null) | (null) |

我想将code_1和code_2堆叠到一个列中,这可以通过使用:

来完成
select id, code, pair_1 as pair
  from source
       unpivot (code for code_ in (code_1, code_2)) as unpvt;

,产生以下输出:

| id | code |   pair |
|----|------|--------|
|  1 |   a1 |     b1 |
|  1 |   a2 |     b1 |
|  2 |   a3 | (null) |
|  2 |   a4 | (null) |
|  3 |   a5 |     b2 |
|  4 |   a6 | (null) |
|  5 |   a7 |     b3 |
|  6 |   a8 | (null) |

,但我还想捕捉code_1pair_1配对的情况,即只要code来自code_1,它就会使用pair_1中的值1}} pair;每当code来自code_2时,null始终使用pair。{/ p>

因此,例如,给定原始表,目标表应该是这样的:

| id | code |   pair |
|----|------|--------|
|  1 |   a1 |     b1 |
|  2 |   a2 | (null) |
|  3 |   a3 | (null) |
|  4 |   a4 | (null) |
|  5 |   a5 |     b2 |
|  6 |   a6 | (null) |
|  7 |   a7 | (null) |
|  8 |   a8 | (null) |

DDL

http://sqlfiddle.com/#!18/743a5/16

create table source (
  id     int identity(1, 1) primary key,
  code_1 varchar(10),
  code_2 varchar(10),
  pair_1 varchar(10)
);
insert into source values
('a1', 'a2', 'b1'),
('a3', 'a4', null),
('a5', null, 'b2'),
('a6', null, null),
(null, 'a7', 'b3'),
(null, 'a8', null),
(null, null, 'b4'),
(null, null, null);


create table target (
  id   int identity(1, 1) primary key,
  code varchar(10),
  pair varchar(10)
);
insert into target values
('a1', 'b1'),
('a2', null),
('a3', null),
('a4', null),
('a5', 'b2'),
('a6', null),
('a7', null),
('a8', null);

1 个答案:

答案 0 :(得分:1)

  

你不能做简单的UNION ALL吗?

尝试以下查询

SELECT * FROM
(
SELECT id, code_1 as code, pair_1 as pair FROM source WHERE code_1 IS NOT NULL
UNION ALL 
SELECT id, code_2 as code, NULL as pair FROM source WHERE code_2 IS NOT NULL
) UnionTable
ORDER BY id