Для этого примера у меня есть три таблицы (индивидуальная, бизнес и 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 для этого вопроса. ( Ссылка )
Заранее спасибо за любой ввод.