根据另一个表数据创建另一个表和列

时间:2020-10-07 07:34:48

标签: sql oracle

我有下表:

表1

Create  table Table1 (Col1 Varchar2(50) not null, Col2 Varchar2(50), Col3 Varchar2(50));

Insert into Table1 (col1, col2, col3) values 
('RED','aa','11,22,33'),
('Green','bb','33'),
('blue','bb','11,44'), 
('yellow','bb','55,66'), 
('orange','bb','22,33');

enter image description here

Colx_11将具有基于表1的值,表1中的Col3记录中有多少条记录具有11作为值。

类似地获得22,33和其他值。

输出表2 enter image description here

1 个答案:

答案 0 :(得分:2)

由于未知的oracle版本,我会尽可能给出答案,

由于oracle中没有可用的特定预定义函数来轻松拆分以逗号分隔的记录,因此我们需要使用regular expression对其进行拆分,然后计算出现的次数。

使用条件聚合(适用于8i以上的任何版本):

select sum(case when split_number = 11 then 1 else 0 end) as col_11
      ,sum(case when split_number = 22 then 1 else 0 end) as col_22
      ,sum(case when split_number = 33 then 1 else 0 end) as col_33
      ,sum(case when split_number = 44 then 1 else 0 end) as col_44
      ,sum(case when split_number = 55 then 1 else 0 end) as col_55
      ,sum(case when split_number = 66 then 1 else 0 end) as col_66
  from table1 t1
  join (select distinct col3,regexp_substr(col3,'[^,]+', 1, level) split_number
         from table1 t2
        connect by regexp_substr(col3, '[^,]+', 1, level) is not null) t2
    on t2.col3 = t1.col3;

使用PIVOT和JOIN(适用于任何版本== 11g):

select *
  from
(
select split_number
  from table1 t1
  join (select distinct col3,regexp_substr(col3,'[^,]+', 1, level) split_number
         from table1 t2
        connect by regexp_substr(col3, '[^,]+', 1, level) is not null) t2
    on t2.col3 = t1.col3
)
pivot
(
 count(*)
 for split_number in ( 11 as col_11
                     , 22 as col_22
                     , 33 as col_33
                     , 44 as col_44
                     , 55 as col_55
                     , 66 as col_66)
);

使用PIVOT和LATERAL(适用于任何版本== 12c):

select *
  from
(
select split_number
  from table1 t1,
  lateral (select regexp_substr(col3,'[^,]+', 1, level) split_number
             from dual
           connect by regexp_substr(col3, '[^,]+', 1, level) is not null) t2
)
pivot
(
 count(*)
 for split_number in ( 11 as col_11
                     , 22 as col_22
                     , 33 as col_33
                     , 44 as col_44
                     , 55 as col_55
                     , 66 as col_66)
);

我仍然要在此提及上述查询的缺点,即明确提及诸如col_11col_22 ...之类的列,要使其具有动态性,我们需要动态SQL或其他带有XML个查询。

相关问题