【问题标题】:Oracle Conditional where clauseOracle 条件 where 子句
【发布时间】:2015-05-15 15:37:55
【问题描述】:

有没有办法编写具有以下功能的查询,添加 where 子句作为条件方式,

      select e.emp_id, emp.admin_user from employees e

如果 emp.admin != 'Y'

然后

使用 where 子句运行查询

否则

没有 where 子句的查询运行?

【问题讨论】:

  • 一个简单的解决方案是添加一个 if 语句来检查条件,然后有两个 select,一个带有 where 子句,一个不依赖 if 语句的结果。
  • 您可以在 where 子句中使用 CASE 表达式。看我的回答。
  • select * from employees WHERE project_id in (CASE WHEN employees.ADMIN_USER != 'Y' then THEN (select distinct project_id from PROJECTS_ACCESSIBLE_TO_USER where emp_id = 1002332) ELSE ename END)

标签: oracle oracle11g case conditional-statements where


【解决方案1】:

WHERE 子句中使用 CASE 表达式应该可以解决问题。当您说如果不满足条件时不需要 where 子句,那么您想要的只是WHERE 1 = 1 之类的条件,即当不满足条件时返回所有行。所以,你需要让不满足的条件一如既往TRUE

例如,

我有一张员工表,

SQL> SELECT empno, ename, deptno
  2  FROM emp;

     EMPNO ENAME          DEPTNO
---------- ---------- ----------
      7369 SMITH              20
      7499 ALLEN              30
      7521 WARD               30
      7566 JONES              20
      7654 MARTIN             30
      7698 BLAKE              30
      7782 CLARK              10
      7788 SCOTT              20
      7839 KING               10
      7844 TURNER             30
      7876 ADAMS              20
      7900 JAMES              30
      7902 FORD               20
      7934 MILLER             10

14 rows selected.

SQL>

我想选择员工的详细信息,如果部门是20则使用where子句,否则返回所有员工的详细信息,但过滤符合where条件的部门。

SQL> SELECT empno, ename, deptno
  2  FROM emp
  3  WHERE ename =
  4    CASE
  5      WHEN deptno = 20
  6      THEN 'SCOTT'
  7      ELSE ename
  8    END
  9  /

     EMPNO ENAME          DEPTNO
---------- ---------- ----------
      7499 ALLEN              30
      7521 WARD               30
      7654 MARTIN             30
      7698 BLAKE              30
      7782 CLARK              10
      7788 SCOTT              20
      7839 KING               10
      7844 TURNER             30
      7900 JAMES              30
      7934 MILLER             10

10 rows selected.

SQL>

因此,对于 20 部门,过滤器由 where 子句应用,我只得到 ename SCOTT 的行,对于其他人,它返回所有行。

【讨论】:

  • select * from employees WHERE project_id in (CASE WHEN employees.ADMIN_USER != 'Y' then THEN (select distinct project_id from PROJECTS_ACCESSIBLE_TO_USR where emp_id = 1002332) ELSE ename END) 这个查询是否正确?
  • 最好加入两个表。提供表格详细信息。编辑您的问题和所需的详细信息。
  • 如果对您有帮助,请将其标记为已回答。它也会帮助其他人。
【解决方案2】:

为了简单起见,在这种情况下我会选择 union 子句,这样您就可以根据需要使 where 子句变得复杂。我试图从上面的评论中猜测你的表结构,让我们看看这个例子:

SQL> create table employees (emp_id number, admin_user number, project_id number);

表已创建。

SQL> create table project_accessible_to_user (emp_id number, project_id number);

表已创建。

现在将所有两个查询进行简单的联合,一个带有 where 条件,另一个没有它

SQL> select * from employees e where e.admin_user!='Y' and project_id in

(select project_id from project_accessible_to_user where emp_id=e.emp_id)    

 union all 

select * from employees e where (e.admin_user is null or   
 e.admin_user='Y');

从性能的角度来看,UNION ALL 比 UNION 更好,因为这意味着它不检查相交值,因此如果有任何相交值,它将返回重复值。但是在这种情况下,它已经被 admin_user 上的条件过滤了,所以这些重复项不会发生。

【讨论】:

  • UNION 可能会成为性能杀手……值得一提的是,即使是更复杂的查询,人们也会开始使用它,而这正是问题发生的地方。我已经见过很多次了——使用 UNION ALL 进行极长的查询(使用 UNION 更糟)只是为了通过一次查询来实现结果......无论成本如何......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-06
  • 1970-01-01
  • 1970-01-01
  • 2014-09-30
相关资源
最近更新 更多