Попытка избежать дублирования в запросе Oracle с псевдонимом таблицы, приводящим к ошибке «отсутствует правильная скобка» - PullRequest
1 голос
/ 14 апреля 2020

Я пытаюсь написать запрос, который собирает список идентификационных номеров из двух таблиц.

Первая часть запроса выбирает идентификационные номера сотрудников, которые начинаются с 'B' и были созданы после 1 января, 2020 из таблицы, содержащей основной список идентификаторов. Во второй части запроса рассматривается другая таблица, содержащая идентификаторы команд (которые состоят из двух или более идентификаторов сотрудников) - в основном я хочу выбрать любой идентификатор группы, который содержит идентификатор сотрудника, который соответствует критериям в первом запросе.

У меня работает приведенный ниже код, и он возвращает правильные данные:

SELECT 
    emp_id AS id
FROM 
    emp_master_view 
WHERE 
    emp_id IN
(
    SELECT DISTINCT t.team_id AS id
    FROM team_master_view t
    WHERE t.emp_id IN
    (
        SELECT emp_id
        FROM emp_master_view
        WHERE SUBSTR(emp_id, 1, 1) IN ('B')
        AND crt_date >= TO_DATE('2020-01-01', 'yyyy-mm-dd')
    )
)
UNION SELECT emp_id AS id
FROM emp_master_view
WHERE SUBSTR(emp_id, 1, 1) IN ('B')
AND crt_date >= TO_DATE('2020-01-01', 'yyyy-mm-dd')

Однако я ненавижу дублирование, которое мне нужно использовать с оператором union select ... Я пытался использовать псевдоним таблицы как это:

SELECT 
    emp_id
FROM 
    emp_master_view 
WHERE 
    emp_id IN
(
    SELECT DISTINCT t.team_id AS emp_id
    FROM team_master_view t
    WHERE team_id IN
    (
        SELECT emp_id
        FROM emp_master_view
        WHERE SUBSTR(emp_id, 1, 1) IN ('B')
        AND crt_date >= TO_DATE('2020-01-01', 'yyyy-mm-dd')
    ) emp
)
UNION SELECT emp_id
FROM emp

... но это вызывает ошибку «отсутствует правильная скобка». Я знаю, что делаю какую-то глупую ошибку, но я попробовал несколько вариантов и не могу заставить ее работать, не дублируя выбор полностью, поэтому я машу белым флагом. Кто-нибудь может указать правильный способ использования псевдонима таблицы в этом случае?

Редактировать

Пример данных будет следующим:

emp_master_view содержит основной список для каждого идентификационного номера, включая команды:

EMP_MASTER_VIEW
+--------+------------+
| emp_id |  crt_date  |
+--------+------------+
| B56    | 2019-11-02 |
| B99    | 2020-03-02 |
| S34    | 2020-03-02 |
| RZF    | 2020-04-01 |
| RQR    | 2020-04-01 |
+--------+------------+

team_master_view содержит только идентификаторы команды, и для каждого отдельного сотрудника в команде есть строка:

TEAM_MASTER_VIEW
+---------+--------+
| team_id | emp_id |
+---------+--------+
| RZF     | B99    |
| RZF     | B56    |
| RQR     | B56    |
| RQR     | S34    |
+---------+--------+

Желаемые результаты - вытащите все идентификаторы в emp_master_view, которые соответствуют критериям, и ТАКЖЕ выберите все идентификаторы команд из team_master_view, где этот идентификатор группы содержит один из идентификаторов сотрудников, выбранных в первой части запроса.

Учитывая приведенные выше таблицы, он выберет B99 из emp_master_view, поскольку это единственный код, который соответствует обоим критериям (начинается с 'B' и создается после 1 января 2020 года). Он также выберет RZF из team_master_view, потому что этот идентификатор команды содержит B99. Конечный набор результатов будет состоять из двух строк:

B99
RZF

Надеюсь, это имеет смысл ...

1 Ответ

2 голосов
/ 14 апреля 2020

Поскольку вы хотите использовать один и тот же запрос более одного раза, вы можете использовать предложение WITH для факторинга подзапроса :

with data as
(
    SELECT emp_id AS id
    FROM emp_master_view
    WHERE SUBSTR(emp_id, 1, 1) IN ('B')
    AND crt_date >= TO_DATE('2020-01-01', 'yyyy-mm-dd')
)
SELECT 
    emp_id AS id
FROM 
    emp_master_view 
WHERE 
    emp_id IN
(
    SELECT DISTINCT t.team_id AS id
    FROM team_master_view t
    WHERE t.emp_id IN
    (
        SELECT emp_id
        FROM data)
)
UNION 
select emp_id from data;

Update :

После того, как вы разместили данные таблицы и требования, она выглядит как простая JOIN между двумя таблицами:

SELECT e.emp_id, 
       t.team_id
FROM
    emp_master_view e
    JOIN team_master_view t 
    ON e.emp_id = t.emp_id
WHERE
    e.emp_id LIKE 'B%'
    AND e.crt_date >= TO_DATE('2020-01-01', 'yyyy-mm-dd');
...