【问题标题】:In Oracle SQL how to make select to return all rows whose ID is in a list?在 Oracle SQL 中,如何使选择返回 ID 在列表中的所有行?
【发布时间】:2020-06-06 02:59:27
【问题描述】:

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。除了员工id,所有文本列都可以为null,而数字列全部为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 |
+-------------+------------+-----------+----------+--------------+-----------+------------+--------+----------------+------------+---------------+

如何修改查询以实现此目的?

【问题讨论】:

  • 构造一个硬编码的值列表,然后将其左连接到您的表。这是一个关于构建列表的问题。 stackoverflow.com/questions/6345635/…
  • 你想做什么?这只是感觉错误
  • @Kevin 我需要逐项比较两个表。一个表在 Excel 电子表格中,而另一个表在数据库中。 Excel 电子表格有一个我需要检查的固定实体列表。它可以包含比查询返回的更多的实体。目前我无法从查询中复制一整列,因为我必须跳过 Excel 中但不在查询中的条目。

标签: sql oracle


【解决方案1】:

创建一个临时变量或表,其中包含您要查看的 ID 列表。选择该变量,然后选择表中的字段,其中 id 在您的临时列表中。

【讨论】:

    【解决方案2】:

    执行此操作的一种方法是将您希望在输出中看到的员工 ID 放入一个表中,例如 empIdTable,然后对其进行左连接。

    select * from 
    empIdTable I
    LEFT JOIN employees E
    on I.employee_id = E.employee_id
    

    【讨论】:

      【解决方案3】:

      这可能是一种方法:

      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 需要检查,这将是一个坏主意。

      【讨论】:

      • 与 t (select * from hr.employees) 而不是仅仅加入 hr.employees 有什么意义?
      • 是的,你是对的。我只是在做一些我自己的测试,所以我就这样离开了。
      【解决方案4】:

      您想使用left join,但您需要一个您正在寻找的 id 的来源。可以使用派生表:

      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。他还得扔一堆NVL。在选择 206 行的末尾还需要另一个联合
      【解决方案5】:

      将大量 ID 联合在一起进行检查的另一种方法是使用集合并将其视为表表达式,然后从该集合进行左连接:

      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 表达式来识别不匹配的行可以让您更有选择性。

      如有必要,可以从应用程序传入集合,例如通过将数组转换为绑定变量,这比动态构建联合要容易得多。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-30
        • 1970-01-01
        相关资源
        最近更新 更多