В Oracle SQL как сделать выбор, чтобы вернуть все строки, чей идентификатор находится в списке? - PullRequest
0 голосов
/ 21 февраля 2020

Используя таблицу HR.employees в качестве примера. Предположим, я хочу проверить информацию для сотрудников 205, 206 и 207. Обратите внимание, что 207 нет в таблице. Это запрос, который я выполню:

select * from HR.employees
where employee_id in ('205', '206', '207');

Вот результаты, которые я получаю:

+-------------+------------+-----------+----------+--------------+-----------+------------+--------+----------------+------------+---------------+
| EMPLOYEE_ID | FIRST_NAME | LAST_NAME |  EMAIL   | PHONE_NUMBER | HIRE_DATE |   JOB_ID   | SALARY | COMMISSION_PCT | MANAGER_ID | DEPARTMENT_ID |
+-------------+------------+-----------+----------+--------------+-----------+------------+--------+----------------+------------+---------------+
|         205 | Shelley    | Higgins   | SHIGGINS | 515.123.8080 | 02-06-07  | AC_MGR     |  12008 |                |        101 |           110 |
|         206 | William    | Gietz     | WGIETZ   | 515.123.8181 | 02-06-07  | AC_ACCOUNT |   8300 |                |        205 |           110 |
+-------------+------------+-----------+----------+--------------+-----------+------------+--------+----------------+------------+---------------+

Несмотря на то, что 207 отсутствует в таблице, я все еще хочу видеть 207 в запросе возвращение. Все текстовые столбцы, кроме идентификатора сотрудника, могут быть нулевыми, а числовые столбцы равны 0. Например:


+-------------+------------+-----------+----------+--------------+-----------+------------+--------+----------------+------------+---------------+
| EMPLOYEE_ID | FIRST_NAME | LAST_NAME |  EMAIL   | PHONE_NUMBER | HIRE_DATE |   JOB_ID   | SALARY | COMMISSION_PCT | MANAGER_ID | DEPARTMENT_ID |
+-------------+------------+-----------+----------+--------------+-----------+------------+--------+----------------+------------+---------------+
|         205 | Shelley    | Higgins   | SHIGGINS | 515.123.8080 | 02-06-07  | AC_MGR     |  12008 |                |        101 |           110 |
|         206 | William    | Gietz     | WGIETZ   | 515.123.8181 | 02-06-07  | AC_ACCOUNT |   8300 |                |        205 |           110 |
|         207 | Null       | Null      | 0        | Null         | Null      | Null       |      0 |              0 |         0  |             0 |
+-------------+------------+-----------+----------+--------------+-----------+------------+--------+----------------+------------+---------------+

Как мне изменить запрос, чтобы добиться этого?

Ответы [ 5 ]

3 голосов
/ 21 февраля 2020

Альтернативой объединению большого количества идентификаторов для проверки является использование коллекции и обработка ее как табличного выражения, а затем соединение слева:

select t.column_value as employee_id, e.first_name, e.last_name, -- e.email, ...
  case when e.employee_id is null then 0 else e.salary end as salary,
  case when e.employee_id is null then 0 else e.commission_pct end as commission_pct
  -- , ...
from table(sys.odcinumberlist(205, 206, 207)) t
left join employees e on e.employee_id = t.column_value;

EMPLOYEE_ID FIRST_NAME           LAST_NAME                     SALARY COMMISSION_PCT
----------- -------------------- ------------------------- ---------- --------------
        205 Shelley              Higgins                        12000               
        206 William              Gietz                           8300               
        207                                                         0              0

Вы можете использовать nvl() или coalesce() для числовых столбцов, но это установит commission_pct в ноль для всех реальных сотрудников (у которых нет одного набора). Использование выражения case для идентификации несопоставленных строк позволяет вам быть более избирательным.

При необходимости коллекция может быть передана из приложения, например, путем преобразования массива, как переменная связывания, и намного проще, чем строим союз на лету.

2 голосов
/ 21 февраля 2020

Вы хотите использовать left join, но вам нужен источник для идентификаторов, которые вы ищете. Можно использовать производную таблицу:

select *
from (select 205 as employee_id from dual union all
      select 206 as employee_id from dual union all
      select 207 as employee_id from dual
     ) i left join
     HR.employees e
     using (employee_id);

Возвращает NULL значения для несопоставленных столбцов. Если вы действительно хотите другое значение, вам нужно перечислить столбцы.

Обратите внимание, что с предложением using вы можете использовать select * и не получить дубликат employee_id в результате .

0 голосов
/ 21 февраля 2020

Один из способов сделать это - поместить идентификаторы сотрудников, которые вы хотите видеть в выходных данных, в таблицу, например, empIdTable, а затем выполнить левое соединение с ним.

select * from 
empIdTable I
LEFT JOIN employees E
on I.employee_id = E.employee_id
0 голосов
/ 21 февраля 2020

Это может быть один из способов сделать это:

select *
from HR.employees e
right join (
    select '205' employee_id from dual

    union all

    select '206' employee_id from dual

    union all

    select '207' employee_id from dual
) lt
on lt.employee_id = e.employee_id;

Но это будет плохой идеей, если у вас есть много employee_id для проверки.

0 голосов
/ 21 февраля 2020

Создайте временную переменную или таблицу, содержащую список идентификаторов, которые вы хотите увидеть. Выберите эту переменную, затем поля из таблицы, где id находится в вашем временном списке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...