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

How to correlate data and counts from columns to rows in Oracle (19c)?

我相信可能有一种简单的方法可以使用枢轴或分区来解决这些问题,但我似乎找不到合适的解决方案。我通过使用一长串 select sum() 和问题 2 的长解决方案来解决问题 1,其中我只是 select 来自 table 的计数 (*) B where id = id from table A 在 (select) 块中多次但是如果我有大量的 ID,那么这两个解决方案都等于非常长的 SQL 这变得非常乏味和我确定有更好的方法只是在躲避我。

我非常想要允许我包含大量多个 ID 或提供具有 table 个 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) 在 Table B 中的每个 SET 中可以找到来自 Table A 的每个 ID 中的多少以及 (2) 来自 [=] 的每个 ID 中有多少36=] A 可以在 Table B 的每个 SET 中找到,而不能在 Table 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

感谢您提供的所有帮助。

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

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

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

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

问题 1

数据:

create table tbl (id, descr, yr) as
  select 1, 'A', 2021 from dual union all
  select 1, 'B', 2021 from dual union all
  select 1, 'C', 2021 from dual union all
  select 2, 'A', 2021 from dual union all
  select 2, 'B', 2021 from dual union all
  select 2, 'C', 2021 from dual union all
  select 3, 'A', 2019 from dual union all
  select 3, 'B', 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

在第二个问题的最后一部分,您不妨单独使用子查询和 运行 - 旋转其输出的目的是什么?