【发布时间】:2020-07-28 23:49:21
【问题描述】:
对于此示例,我有三个表(个人、业务和 ind_to_business)。个人拥有关于人的信息。商业有关于商业的信息。 ind_to_business 包含有关哪些人与哪些业务相关联的信息。以下是他们的 DDL:
CREATE TABLE individual
(
ID INTEGER PRIMARY KEY,
NAME VARCHAR2(100) NOT NULL,
ENTERPRISE_ID VARCHAR2(25) NOT NULL UNIQUE
);
CREATE TABLE business
(
ID INTEGER PRIMARY KEY,
NAME VARCHAR2(100) NOT NULL,
ENTERPRISE_ID VARCHAR2(25) NOT NULL UNIQUE
);
CREATE TABLE ind_to_business
(
ID INTEGER PRIMARY KEY,
IND_ID REFERENCES individual(id),
BUS_ID REFERENCES business(id),
START_DT DATE NOT NULL,
END_DT DATE
);
我正在寻找为每个人显示一行的最佳方式。如果它们与一项业务相关联,我想显示该业务的ENTERPRISE_ID。如果它们与多个业务相关联,我想显示默认值“多个”。它们将始终与企业相关联,因此不需要LEFT JOIN。它们也可以多次与企业相关联(离开和回来)。同一业务的多条记录将被聚合。
所以对于以下示例数据:
个人:
+----+------------+---------------+
| ID | NAME | ENTERPRISE_ID |
+----+------------+---------------+
| 1 | John Smith | 53a23B7 |
| 2 | Jane Doe | 63f2a35 |
+----+------------+---------------+
业务:
+----+----------+---------------+
| ID | NAME | ENTERPRISE_ID |
+----+----------+---------------+
| 3 | ABC Corp | 2a34d9b |
| 4 | XYZ Inc | 34bf21e |
+----+----------+---------------+
ind_to_business
+----+--------+--------+-------------+-------------+
| ID | IND_ID | BUS_ID | START_DT | END_DT |
+----+--------+--------+-------------+-------------+
| 5 | 1 | 3 | 01-JAN-2000 | 31-DEC-2002 |
| 6 | 1 | 3 | 01-JAN-2015 | |
| 7 | 2 | 3 | 01-JAN-2000 | |
| 8 | 2 | 4 | 01-MAR-2006 | 05-JUN-2010 |
| 9 | 2 | 4 | 15-DEC-2019 | |
+----+--------+--------+-------------+-------------+
我希望得到以下输出:
+---------+------------+------------+
| IND_ID | NAME | LINKED_BUS |
+---------+------------+------------+
| 53a23B7 | John Smith | 2a34d9b |
| 63f2a35 | Jane Doe | Multiple |
+---------+------------+------------+
这是我当前的查询:
SELECT DISTINCT
sub.ind_id,
sub.name,
DECODE(sub.bus_count, 1, sub.bus_id, 'Multiple') AS LINKED_BUS
FROM (SELECT i.enterprise_id AS IND_ID,
i.name,
b.enterprise_id AS BUS_ID,
COUNT(DISTINCT b.enterprise_id) OVER (PARTITION BY i.id) AS BUS_COUNT
FROM individual i
INNER JOIN ind_to_business i2b ON i.id = i2b.ind_id
INNER JOIN business b ON i2b.bus_id = b.id) sub;
我的查询有效,但这是在大型数据集上运行并且需要很长时间才能运行。我想知道是否有人对如何改进这一点有任何想法,以免浪费太多处理(即需要对最终结果执行 DISTINCT 或在内联视图中执行 COUNT(DISTINCT) 仅使用该值在上面的DECODE 中)。
我还为这个问题创建了一个 DBFiddle。 (Link)
提前感谢您的任何意见。
【问题讨论】:
-
无需使用 DISTINCT 两次,您可以在子查询本身中获取不同的数据,然后聚合行。有关详细信息,请参阅我的答案。
标签: sql oracle join group-by query-optimization