如何在 Oracle (19c) 中将数据和计数从列关联到行?

我相信可能有一种简单的方法可以用枢轴或分区来解决这些问题,但我似乎找不到合适的解决方案。我有一个关于问题 1 的解决方案,通过使用一长串 select sum()s 和一个很长的问题 2 解决方案,其中我只是从表 B 中选择 count(*) 其中 id = id 从表 A 中多次(select) 块,但如果我有大量的 ID,这两个解决方案都等于很长的 SQL,这会变得非常乏味,而且我确信有更好的方法让我躲避。

我真的很喜欢允许我包含大量多个 ID 的解决方案,或者为解决方案提供一个 ID 表以供评估。

问题 1:

Table: 
------------------
ID   DESC   YEAR
1     A     2021
1     B     2021
1     C     2021
2     A     2021
2     B     2021
2     C     2021
3     A     2019
3     B     2019

我想按年份计算每个 DESC 的 ID 数。

Expected Result:
------------------
Year  CountA  CountB  CountC
2019    1       1       0
2021    2       2       2

问题 2:

Table A:
------------------
ID  DESC
1    A
2    B
3    C

Table B:
------------------
SET  ID  
10   1   
10   1   
12   1   
13   2   
14   3   

我想看看 (1) 在表 B 的每个 SET 中可以找到表 A 中的每个 ID 有多少个,以及 (2) 在表 B 的每个 SET 中可以找到表 A 中的每个 ID 有多少个,以及不在表 B 的任何其他 SET 中(唯一匹配)。

Expected Result 1:
------------------
ID  Count10  Count12  Count13  Count14
1      2        1        0        0
2      0        0        1        0
3      0        0        0        1

Expected Result 2:
------------------
ID  UniqueCount10  UniqueCount12  UniqueCount13  UniqueCount14
1         0              0              0              0
2         0              0              1              0
3         0              0              0              1

感谢您的任何帮助。

tmroybq 回答:如何在 Oracle (19c) 中将数据和计数从列关联到行?

所有三个问题都可以通过旋转来解决(将问题 2 称为“两个不同的问题”),尽管尚不清楚结果 2 的用途是什么(在第二个问题中;请参阅我对您的评论)。

请注意,descset 是保留关键字,而 year 是关键字,因此不应将它们用作列名。我改为descrset_(带下划线)和yr。另外,我不在输出中对列名使用双引号;全大写的列名就好了。

在第二个问题中,不清楚为什么需要表 A。是否有一些 id 值根本没有出现在表 B 中,但您仍然希望它们出现在最终输出中?如果是这样,您需要将我的半连接更改为外部连接;留作练习,因为这是一个不同(而且更基本)类型的问题。

在第一个问题中,您必须对子查询的结果进行透视,它仅从基表中选择相关列。第二个问题没有这样的必要(除非你的表有其他不应考虑的列 - 留给你弄清楚)。

问题 1

数据

create table tbl (id,descr,yr) as
  select 1,'A',2021 from dual union all
  select 1,'B','C',2021 from dual union all
  select 2,2021 from dual union all
  select 3,2019 from dual union all
  select 3,2019 from dual
;

查询和输出

select *
from   (select descr,yr from tbl)
pivot  (count(*) for descr in ('A' as count_a,'B' as count_b,'C' as count_c))
order  by yr
;

  YR COUNT_A COUNT_B COUNT_C
---- ------- ------- -------
2019       1       1       0
2021       2       2       2

问题 2

数据

create table table_a (id,descr) as
  select 1,'A' from dual union all
  select 2,'B' from dual union all
  select 3,'C' from dual
;

create table table_b (set_,id) as
  select 10,1 from dual union all   
  select 10,1 from dual union all   
  select 12,1 from dual union all
  select 13,2 from dual union all
  select 14,3 from dual
;

第 1 部分 - 查询和结果

select *
from   table_b
pivot  (count(*) for set_ in (10 as count_10,12 as count_12,13 as count_13,14 as count_14))
where  id in (select id from table_a)        -- is this needed?
order  by id                                 -- if needed
;

ID COUNT_10 COUNT_12 COUNT_13 COUNT_14
-- -------- -------- -------- --------
 1        2        1        0        0
 2        0        0        1        0
 3        0        0        0        1

第 2 部分 - 查询和结果

select *
from   (
         select id,case count(distinct set_) when 1 then max(set_) end as set_
         from   table_b
         where  id in (select id from table_a)        -- is this needed?
         group  by id
       )
pivot  (count(*) for set_ in (10 as unique_ct_10,12 as unique_ct_12,13 as unique_ct_13,14 as unique_ct_14))
order  by id          -- if needed
;

ID UNIQUE_CT_10 UNIQUE_CT_12 UNIQUE_CT_13 UNIQUE_CT_14
-- ------------ ------------ ------------ ------------
 1            0            0            0            0
 2            0            0            1            0
 3            0            0            0            1

在第二个问题的最后一部分中,您不妨直接获取子查询并单独运行它——旋转其输出的目的是什么?

本文链接:https://www.f2er.com/7036.html

大家都在问