两个类似查询之间的UNPIVOT问题

时间:2017-04-28 20:42:30

标签: sql oracle unpivot

尝试在oracle 12c中解决问题(SQL: query to show how many users have each property (grouped))。

with data (id, name, a, b, c, d) as
(
  select 1, 'name1', 'yes', 'yes', '', 'yes' from dual union all
  select 2, 'name2', 'yes', '', '', 'yes' from dual union all
  select 3, 'name3', '', 'yes', '', 'yes' from dual union all
  select 4, 'name4', 'yes', 'yes', '', 'yes' from dual union all
  select 5, 'name5',  '', '', 'yes', 'yes' from dual 
)
,
coll (a,b,c,d) as
(
  select count(a) a, count(b) b, count(c) c, count(d) d from data
)
select * from coll
unpivot 
(
  val for (col) in (a, b, c, d)
);

工作正常并产生所需的结果。

尽管

with data (id, name, a, b, c, d) as
(
select 1, 'name1', 'yes', 'yes', '', 'yes' from dual union all
select 2, 'name2', 'yes', '', '', 'yes' from dual union all
select 3, 'name3', '', 'yes', '', 'yes' from dual union all
select 4, 'name4', 'yes', 'yes', '', 'yes' from dual union all
select 5, 'name5',  '', '', 'yes', 'yes' from dual 
)
--,
--coll (a,b,c,d) as
--(
select count(a) a, count(b) b, count(c) c, count(d) d from data -- Line 1685
--)
--select * from coll
unpivot 
(
val for (col) in (a, b, c, d)
);

产生以下错误。

  

ORA-00904:" D":无效的标识符   00904. 00000 - "%s:无效标识符"   *原因:
  *行动:   行错误:1,685列:50

有人可以帮忙找出原因吗?

3 个答案:

答案 0 :(得分:0)

with data (id, name, a, b, c, d) as (
  select 1, 'name1', 'yes', 'yes', '',    'yes' from dual union all
  select 2, 'name2', 'yes', '',    '',    'yes' from dual union all
  select 3, 'name3', '',    'yes', '',    'yes' from dual union all
  select 4, 'name4', 'yes', 'yes', '',    'yes' from dual union all
  select 5, 'name5',  '',   '',    'yes', 'yes' from dual 
)
select * from data
unpivot (  val for (col) in (a, b, c, d) );

<强>输出

    ID NAME  COL VAL
------ ----- --- ---
     1 name1 A   yes
     1 name1 B   yes
     1 name1 D   yes
     2 name2 A   yes
     2 name2 D   yes
     3 name3 B   yes
     3 name3 D   yes
     4 name4 A   yes
     4 name4 B   yes
     4 name4 D   yes
     5 name5 C   yes
     5 name5 D   yes

要计算的输出中没有列ABCD

如果您想获得相同的输出,则需要按COL分组:

with data (id, name, a, b, c, d) as (
  select 1, 'name1', 'yes', 'yes', '',    'yes' from dual union all
  select 2, 'name2', 'yes', '',    '',    'yes' from dual union all
  select 3, 'name3', '',    'yes', '',    'yes' from dual union all
  select 4, 'name4', 'yes', 'yes', '',    'yes' from dual union all
  select 5, 'name5',  '',   '',    'yes', 'yes' from dual 
)
select COL, COUNT(*) AS VAL from data
unpivot (  val for (col) in (a, b, c, d) )
GROUP BY col
ORDER BY col;

<强>输出

COL        VAL
--- ----------
A            3
B            3
C            1
D            5

答案 1 :(得分:0)

有问题的查询有所不同。

1)在第一个查询中,您最初计算了各列中非null的数量并unpivot

2)在第二个中,你首先unpivot,并试图计算它们。在您unpivot之后,没有列a,b,c,d。它们将在col之下......正如您所说val for col in (a,b,c,d)。要获得与第一个相同的结果,请使用

select col,count(*) as val 
from data -- Line 1685
unpivot (
         val for col in (a,b,c,d)
        )
group by col

答案 2 :(得分:0)

显然,给定你编写的SELECT子句,如果第二个查询完全有效,结果将全部在一行中,标记为A,B,C,D的四列。如果那 strong>是你想要的,那么你需要条件COUNT:

with data (id, name, a, b, c, d) as
(
select 1, 'name1', 'yes', 'yes', ''   , 'yes' from dual union all
select 2, 'name2', 'yes', ''   , ''   , 'yes' from dual union all
select 3, 'name3', ''   , 'yes', ''   , 'yes' from dual union all
select 4, 'name4', 'yes', 'yes', ''   , 'yes' from dual union all
select 5, 'name5',  ''  , ''   , 'yes', 'yes' from dual 
)
select count(case col when 'A' then 1 end) as a,
       count(case col when 'B' then 1 end) as b,
       count(case col when 'C' then 1 end) as c,
       count(case col when 'D' then 1 end) as d
from data
unpivot 
(
val for (col) in (a, b, c, d)
);

A  B  C  D
-  -  -  -
3  3  1  5

请注意,要检查的值是&#39; A&#39;,&#39; B&#39;&#39; C&#39;和&#39; D&#39;而不是小写版本。在UNPIVOT子句中,如果您不在IN子子句中使用别名,COL列中的值将只是IN子子句中的列的名称(a,b,c,d) ,总是大写(与Oracle一样,所有列名都没有用双引号括起来。)