我有一个查询,它提供了嵌套的WHERE..IN..SELECT
:
id IN (SELECT MAX(id) FROM item WHERE deleted = 0)
我想要做的是将IN
运算符的结果放入SELECT
属性列表中,就像这样:
SELECT id, ... AS ID_IS_IN_MAX
...
部分是TRUE
或FALSE
的精确计算位置。
显然,我不想过多地对查询负担,所以我也想知道这种解决方案的性能是什么。
我想到的一个解决方案是CASE
:
CASE WHEN ... THEN TRUE ELSE FALSE END
这会有用吗?性能怎么样?
答案 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(+)