IN子句的提升结果作为SELECT的属性

时间:2016-09-21 14:47:05

标签: sql oracle

我有一个查询,它提供了嵌套的WHERE..IN..SELECT

id IN (SELECT MAX(id) FROM item WHERE deleted = 0)

我想要做的是将IN运算符的结果放入SELECT属性列表中,就像这样:

SELECT id, ... AS ID_IS_IN_MAX

...部分是TRUEFALSE的精确计算位置。

显然,我不想过多地对查询负担,所以我也想知道这种解决方案的性能是什么。

我想到的一个解决方案是CASE

CASE WHEN ... THEN TRUE ELSE FALSE END

这会有用吗?性能怎么样?

3 个答案:

答案 0 :(得分:2)

您可以使用交叉联接。 MAX()只返回一行,不会影响性能。

SELECT id,
  CASE
    WHEN id = max_id
    THEN 'true'
    ELSE 'false'
  END
FROM your_table a
CROSS JOIN
  (SELECT MAX(id) AS max_id FROM your_table WHERE deleted=0 ) b ;

答案 1 :(得分:2)

使用分析函数可以最好地解决这个问题,这样您就不会多次读取基表。由于您没有发布任何测试数据,下面的解决方案使用SCOTT模式中的EMP表(大多数Oracle安装的标准)和EMPNO而不是ID,但否则它会出现同样的问题。

编辑:从原始答案中删除此段落:您需要添加的任何过滤器(WHERE子句条件)都可以在FROM子句之后。

正如Mareshwaran根据他的回答在评论中指出的那样,我误解了OP的要求。比较应该是针对子集的最大值; WHERE子句不适用于外部SELECT,只适用于MAX的定义。

这可以通过分析函数中的另一个CASE表达式来解决。再次,使用SCOTT.EMP中存在的内容,我将使用"其中deptno = 20"的条件来说明这一点。这也会改变输出(下面显示的内容与原始查询和原始输出不同)。

相反,要求是标记" true"每个EMPNO在其自己的部门中最高,可以使用max(empno)完成,没有案例表达,over(partition by deptno)。不是原始问题的一部分,但密切相关(也许)。

select empno, 
       case when empno = max(case when deptno = 20 then empno end) over () 
                                              then 'true' else 'false' end as is_max 
from   scott.emp;



 EMPNO IS_MAX
------ ------
  7369 false
  7499 false
  7521 false
  7566 false
  7654 false
  7698 false
  7782 false
  7788 false
  7839 false
  7844 false
  7876 false
  7900 false
  7902 true           -- marking highest EMPNO in department 20
  7934 false

答案 2 :(得分:1)

@Maheswaran Ravisankar是对的。
另一种方式

SELECT id, NVL2(max_id, 'true', 'false') AS id_is_in_max
  FROM your_table t1,
       (SELECT MAX(id) AS max_id FROM your_table WHERE deleted = 0 ) t2
 WHERE t1.id = t2.max_id(+)