如果查询没有返回任何内容,我试图在我的结果集中获取一些默认值。我正在尝试nvl
相同的方法,但它没有返回预期的默认值。为了模拟,考虑以下查询,
select nvl(null, '10') from dual where 1=0;
我想10
在给定条件不正确并且查询不返回任何值的情况下获取。但是上面的查询没有返回任何行。
您的查询返回零行。NVL()
不会改变(*)。
正确的解决方案是让执行查询的程序处理 NO_DATA_FOUND 异常,而不是摆弄查询。
但是,您需要一种解决方法,因此这里使用两个子查询,一个用于您的实际查询,一个用于默认查询。
当your_query
返回一个空集时,您会得到:
SQL> with your_qry as
2 ( select col1 from t42 where 1=0 )
3 , dflt as
4 ( select 10 as col1 from dual )
5 select col1
6 from your_qry
7 union all
8 select col1
9 from dflt
10 where not exists (select * from your_qry );
COL1
----------
10
SQL>
当它返回一行时,您会得到以下信息:
SQL> with your_qry as
2 ( select col1 from t42 )
3 , dflt as
4 ( select 10 as col1 from dual )
5 select col1
6 from your_qry
7 union all
8 select col1
9 from dflt
10 where not exists (select * from your_qry );
COL1
----------
12
13
SQL>
WITH 子句在这里是可选的,它只是使编写查询更容易而不会重复。这将产生相同的结果:
select col1
from t42
where col0 is null
union all
select 10
from dual
where not exists (select col1
from t42
where col0 is null)
;
(*)好的,有一些解决方案使用NVL()
聚合COALESCE()
来做到这一点。正如这个问题所提出的那样,它们在单行中使用单列投影,但是当实际查询具有多于一行和/或多于一列时,它们就会崩溃。聚合会改变结果。
所以这看起来没问题...
SQL> with cte as (
2 select 'Z' as col0, 12 as col1 from dual where 1=0 union all
3 select 'X' as col0, 13 as col1 from dual where 1=0 )
4 select
5 nvl(max(col0), 'Y') as col0, nvl(max( col1), 10) as col1
6 from cte;
COL0 COL1
---------- ----------
Y 10
SQL>
...但这不是那么多:
SQL> with cte as (
2 select 'Z' as col0, 12 as col1 from dual union all
3 select 'X' as col0, 13 as col1 from dual )
4 select
5 nvl(max(col0), 'Y') as col0, nvl(max( col1), 10) as col1
6 from cte;
COL0 COL1
---------- ----------
Z 13
SQL>
可能是这样的东西是你需要的
WHERE COL > 1
您可以在两个地方类似地更改 WHERE 子句(在这种情况下)。
WITH T(COL) AS(
SELECT 1 FROM DUAL UNION ALL
SELECT 2 FROM DUAL UNION ALL
SELECT 3 FROM DUAL
)
SELECT COL FROM T WHERE COL > 1
UNION ALL
SELECT 10 AS COL FROM DUAL WHERE NOT EXISTS( SELECT 1 FROM T WHERE COL > 1)
您可以使用聚合。聚合查询总是返回一行:
select coalesce(max(null), '10')
from dual
where 1 = 0;
我更喜欢coalesce()
因为nvl()
是coalesce()
ANSI标准函数。但是,nvl()
在这里也可以。