求每组丢失物品的数量(ORACLE SQL)
Find the number of lost items in each group (ORACLE SQL)
假设我有以下 table 和这些记录
Table: COMPARE_INDIV
+----------+--------------+--------------+
| ID_GROUP | INDIV_ID_OLD | INDIV_ID_NEW |
+----------+--------------+--------------+
| 1 | 123 | 567 |
| 1 | 123 | null |
| 1 | 123 | 123 |
| 2 | 891 | null |
| 2 | 891 | 456 |
+----------+--------------+--------------+
我想将条目插入到名为 COUNTS 的 table 中,用于计算 COMPARE_INDIV table 中每个 GROUP_ID 丢失的 INDIV_ID_OLD 的数量。如果每个 GROUP_ID 的 INDIV_ID_NEW 列中不存在 INDIV_ID_OLD,则 INDIV_ID_OLD 将丢失。在这种情况下,计数 table 将如下所示。
Table:计数
+----------+------------+--+
| ID_GROUP | LOST_COUNT | |
+----------+------------+--+
| 1 | 0 | |
| 2 | 1 | |
+----------+------------+--+
我该如何完成这样的事情?
如果我没理解错的话,你可以使用两级聚合:
select id_group, sum(1 - present) as missing
from (select id_group, indiv_id_old,
max(case when individ_id_new = indiv_id_old then 1 else 0 end) as present
from COMPARE_INDIV ci
group by id_group, indiv_id_old
) ci
group by id_group;
类似,但只有一个聚合:
SQL> with compare_indiv (id_group, indiv_id_old, indiv_id_new) as
2 -- sample data
3 (select 1, 123, 567 from dual union all
4 select 1, 123, null from dual union all
5 select 1, 123, 123 from dual union all
6 select 2, 891, null from dual union all
7 select 2, 891, 456 from dual
8 ),
9 temp as
10 -- SUM will be 0 if nothing matches
11 (select id_group,
12 sum(case when indiv_id_old = indiv_id_new then 1 else 0 end) sumon
13 from compare_indiv
14 group by id_group
15 )
16 -- final result
17 select id_group,
18 case when sumon = 0 then 1 else 0 end lost_count
19 from temp
20 /
ID_GROUP LOST_COUNT
---------- ----------
1 0
2 1
SQL>
也许存在更好的形式,但这是适合您的一种解决方案
INSERT INTO COUNTS
SELECT A.ID_GROUP , sum(A.is_lost) LOST_COUNT
FROM
(
SELECT A.ID_GROUP , A.INDIV_ID_OLD
,NVL((
SELECT 0
FROM COMPARE_INDIV B
WHERE A.ID_GROUP = B.ID_GROUP
AND A.INDIV_ID_OLD = B.INDIV_ID_NEW
AND ROWNUM = 1
),1) is_lost
FROM COMPARE_INDIV A
GROUP BY A.ID_GROUP , A.INDIV_ID_OLD
) A
GROUP BY A.ID_GROUP
假设我有以下 table 和这些记录
Table: COMPARE_INDIV
+----------+--------------+--------------+
| ID_GROUP | INDIV_ID_OLD | INDIV_ID_NEW |
+----------+--------------+--------------+
| 1 | 123 | 567 |
| 1 | 123 | null |
| 1 | 123 | 123 |
| 2 | 891 | null |
| 2 | 891 | 456 |
+----------+--------------+--------------+
我想将条目插入到名为 COUNTS 的 table 中,用于计算 COMPARE_INDIV table 中每个 GROUP_ID 丢失的 INDIV_ID_OLD 的数量。如果每个 GROUP_ID 的 INDIV_ID_NEW 列中不存在 INDIV_ID_OLD,则 INDIV_ID_OLD 将丢失。在这种情况下,计数 table 将如下所示。
Table:计数
+----------+------------+--+
| ID_GROUP | LOST_COUNT | |
+----------+------------+--+
| 1 | 0 | |
| 2 | 1 | |
+----------+------------+--+
我该如何完成这样的事情?
如果我没理解错的话,你可以使用两级聚合:
select id_group, sum(1 - present) as missing
from (select id_group, indiv_id_old,
max(case when individ_id_new = indiv_id_old then 1 else 0 end) as present
from COMPARE_INDIV ci
group by id_group, indiv_id_old
) ci
group by id_group;
类似,但只有一个聚合:
SQL> with compare_indiv (id_group, indiv_id_old, indiv_id_new) as
2 -- sample data
3 (select 1, 123, 567 from dual union all
4 select 1, 123, null from dual union all
5 select 1, 123, 123 from dual union all
6 select 2, 891, null from dual union all
7 select 2, 891, 456 from dual
8 ),
9 temp as
10 -- SUM will be 0 if nothing matches
11 (select id_group,
12 sum(case when indiv_id_old = indiv_id_new then 1 else 0 end) sumon
13 from compare_indiv
14 group by id_group
15 )
16 -- final result
17 select id_group,
18 case when sumon = 0 then 1 else 0 end lost_count
19 from temp
20 /
ID_GROUP LOST_COUNT
---------- ----------
1 0
2 1
SQL>
也许存在更好的形式,但这是适合您的一种解决方案
INSERT INTO COUNTS
SELECT A.ID_GROUP , sum(A.is_lost) LOST_COUNT
FROM
(
SELECT A.ID_GROUP , A.INDIV_ID_OLD
,NVL((
SELECT 0
FROM COMPARE_INDIV B
WHERE A.ID_GROUP = B.ID_GROUP
AND A.INDIV_ID_OLD = B.INDIV_ID_NEW
AND ROWNUM = 1
),1) is_lost
FROM COMPARE_INDIV A
GROUP BY A.ID_GROUP , A.INDIV_ID_OLD
) A
GROUP BY A.ID_GROUP