将表的前两列堆叠成一列,保留与第三列的关系

时间:2018-03-02 21:28:05

标签: sql-server tsql unpivot

这个问题几乎this question完全相同,但当时我还没有意识到按唯一键id对行的排序不是&#实际上在那里。无论如何,让我用正确的架构重复这个问题。

我的表格如下所示:

| seq | code_1 | code_2 | pair_1 |
|-----|--------|--------|--------|
|   1 |     a1 |     b1 |     c1 |
|   2 |     a2 |     b2 | (null) |
|   3 |     a3 | (null) |     c2 |
|   4 |     a4 | (null) | (null) |

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

来完成
select row_number() over (order by seq), code, pair_1 as pair
  from source
       unpivot (code for code_ in (code_1, code_2)) as unpvt;

,产生以下输出:

| seq | code |   pair |
|-----|------|--------|
|   1 |   a1 |     c1 |
|   2 |   b1 |     c1 |
|   3 |   a2 | (null) |
|   4 |   b2 | (null) |
|   5 |   a3 |     c2 |
|   6 |   a4 | (null) |

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

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

| seq | code |   pair |
|-----|------|--------|
|   1 |   a1 |     c1 |
|   2 |   b1 | (null) |
|   3 |   a2 | (null) |
|   4 |   b2 | (null) |
|   5 |   a3 |     c2 |
|   6 |   a4 | (null) |

DDL

http://sqlfiddle.com/#!18/3fecf/9

create table source (
  seq    int,
  code_1 varchar(10),
  code_2 varchar(10),
  pair_1 varchar(10)
);
insert into source values
(1, 'a1', 'b1', 'c1'),
(2, 'a2', 'b2', null),
(3, 'a3', null, 'c2'),
(4, 'a4', null, null);

create table target (
  seq    int,
  code   varchar(10),
  pair   varchar(10)
);
insert into target values
(1, 'a1', 'c1'),
(2, 'b1', null),
(3, 'a2', null),
(4, 'b2', null),
(5, 'a3', 'c2'),
(6, 'a4', null);

1 个答案:

答案 0 :(得分:1)

我可能在这里遗漏了一些东西,但我认为UNION ALL会做到这一点:

WITH CTE AS
(
    SELECT seq, code_1 as code, pair_1, 1 as codeType
    FROM source
    WHERE code_1 IS NOT NULL
    UNION ALL
    SELECT seq, code_2, NULL, 2
    FROM source
    WHERE code_2 IS NOT NULL
) 
SELECT seq, code, pair_1 as pair
FROM CTE
ORDER BY seq, codeType

See a live demo on rextester.