我有一个oracle DB w /表包含与人关联的记录(基于ID)。记录分类为类别= 1,2或3。
我想说如下:
- 只有1类记录(没有类别= 2或3)的人数#
- 只有2类记录(没有类别= 1或3)的人数#
- 只有3类记录(没有类别= 1或2)的人数#
- 同时拥有1类和1类人员的人数2条记录(无类别= 3)
- 同时拥有1类和1类人员的人数3条记录(无类别= 2)
- 所有类别记录的人数#1,2和& 3
- 同时拥有2类和2类的人数3条记录(无类别= 1)
我只能想到以下解决方案(针对每种情况进行了修改):
select count(*) from table1
where id in (select id from table1 where category=1)
and id not in (select id from table1 where category=2)
and id not in (select id from table1 where category=3)
但是,我相信这是一种非常低效的方式,我想知道是否有人有更快/更好的方式来获取这些信息。
谢谢!
答案 0 :(得分:1)
执行此操作的一种方法是使用listagg()
将类别组合在一起,然后重新聚合:
select categories, count(*)
from (select listagg(t1.category, ',') within group (order by t1.category) as categories, personid
from table1 t1
group by personid
) x
group by categories;
编辑:
如果您需要不同的值:
select categories, count(*)
from (select listagg(t1.category, ',') within group (order by t1.category) as categories, personid
from (select distinct t1.category, t1.personid from table1 t1) t1
group by personid
) x
group by categories;
答案 1 :(得分:0)
这是一个查询,对于每个ID,显示不同类别的计数以及MIN和MAX类别。此查询可用作进一步处理中的子查询(您没有准确解释您希望如何呈现结果)。当COUNT为1时,单个类别是MIN_CAT列中的类别;当COUNT为3时,则该ID的所有三个类别都存在;当COUNT为2时,则存在的两个类别在MIN和MAX列中。无论你需要做什么,都应该非常简单;例如,您现在可以进行GROUP BY CT,MIN_CAT,MAX_CT和计数ID。
我做一个计数(不同类别)以允许非唯一(id, category)
的可能性 - 如我在WITH子句中包含的示例数据中所示(这不是SQL查询的一部分!)
with
test_data ( id, category ) as (
select 101, 3 from dual union all
select 101, 1 from dual union all
select 101, 3 from dual union all
select 104, 2 from dual union all
select 105, 2 from dual union all
select 105, 2 from dual union all
select 105, 1 from dual union all
select 106, 1 from dual union all
select 106, 2 from dual union all
select 106, 3 from dual union all
select 106, 3 from dual
)
select id,
count(distinct category) as ct,
min(category) as min_cat,
max(category) as max_cat
from test_data
group by id
;
ID CT MIN_CAT MAX_CAT
--- -- ------- -------
101 2 1 3
105 2 1 2
104 1 2 2
106 3 1 3
答案 2 :(得分:0)
Oracle安装程序:
CREATE TABLE test_data ( id, category ) as
select 101, 3 from dual union all
select 101, 1 from dual union all
select 101, 3 from dual union all
select 104, 2 from dual union all
select 105, 2 from dual union all
select 105, 2 from dual union all
select 105, 1 from dual union all
select 106, 1 from dual union all
select 106, 2 from dual union all
select 106, 3 from dual union all
select 106, 3 from dual union all
select 107, 1 from dual union all
select 107, 3 from dual;
<强>查询强>:
SELECT c1,
c2,
c3,
LTRIM(
DECODE( c1, 1, ',1' ) || DECODE( c2, 1, ',2' ) || DECODE( c3, 1, ',3' ),
','
) AS categories,
COUNT(1) AS num_people,
LISTAGG( id, ',' ) WITHIN GROUP ( ORDER BY id ) AS people
FROM ( SELECT DISTINCT * FROM test_data )
PIVOT ( COUNT(1) FOR category IN ( 1 AS c1, 2 AS c2, 3 AS c3 ) )
GROUP BY c1, c2, c3;
<强>输出强>:
C1 C2 C3 CATEGORIES NUM_PEOPLE PEOPLE
-- -- -- ---------- ---------- ----------
0 1 0 2 1 104
1 0 1 1,3 2 101,107
1 1 0 1,2 1 105
1 1 1 1,2,3 1 106