用Empyt值取消多列的显示

时间:2019-07-12 16:14:21

标签: sql multiple-columns unpivot

我有一个表 QUESTIONAIRE ,其中的列为 ID,Q1,Q2,Q3,R1,R2,R3。数据类似于:

ID , Q1 , Q2 , Q3 , R1 , R2 , R3 
==   ==   ==   ==   ==   ==   ==
1,   A,   B,   C,   Y,  NULL,  N
2,   Aa,  Bb,  Cc,  -,  N,     Y

我想按以下方式安排它:

ID, QUESTION, ANSWER
==  ========  ======
1,   A,       Y
1,   B,       NULL
1,   C,       N
2,   Aa,      -
2,   Bb,      N
2,   Cc,      Y

3 个答案:

答案 0 :(得分:0)

仅使用UNION 假设您正在创建一个新表unpivoted 插入内容为:

INSERT INTO unpivoted
SELECT
id, Q1, R1

UNION

SELECT
id, Q2, R2

UNION

SELECT
id, Q3, R3

请注意,ID会重复3次,我建议为unpivoted表添加唯一ID

答案 1 :(得分:0)

几个数据库支持横向联接。这是表达这种逻辑的一种更有效的方法。

在SQL Server中,它看起来像:

select q.id, v.q, v.r
from questionnaire q cross apply
     (values (q1, r1), (q2, r2), (q3, r3)) v(q, r);

Oracle和Postgres支持类似的逻辑,尽管语法略有不同。

答案 2 :(得分:0)

如果您的数据库是SQL ServerOracle,则按以下常用语法使用unpivot关键字:

with t(ID , Q1 , Q2 , Q3 , R1 , R2 , R3) as
(
 select 1,  'A',  'B',  'C',  'Y', NULL, 'N' union all
 select 2, 'Aa', 'Bb', 'Cc', '-' ,  'N', 'Y'  
), u2 as
(
select ID, QUESTION, R1, R2, R3, 
       row_number() over (partition by ID order by QUESTION) as rn
  from 
  (
   select u.* from
     (select t.*
        from t) p
   unpivot 
  (
  QUESTION for Title in (Q1,Q2,Q3)
  ) u
  ) u1
)
select ID, QUESTION, 
       case when rn = 1 then R1 
            when rn = 2 then R2 
            when rn = 3 then R3 
       end as ANSWER
  from u2;

ID   QUESTION   ANSWER
--   --------   ------
1    A          Y
1    B  
1    C          N
2    Aa         -
2    Bb         N
2    Cc         Y

除上述与示例数据查询有关的例外外,对于union all数据库,应将from dual union all替换为Oracle

Demo for SQL Server