始终 return 所有行,即使查询没有结果
Always return all row, even when query has no result
我有一个“tt_Results”table,它恰好包含三行/ID,例如:
ID | ResultType
---------------
1 | first
1 | second
1 | third
我的查询如下:
select t.resultType
from tt_Results
where ID = 1;
通常,此查询应该return 所有三行。我的问题是,如果一行或多行不存在,我必须合并所有三个“类型”。
select res.* from
(
select resultType, '1' as exists
from tt_Results
where ID = 1
union all
select 'first' resulttype, '0' as exists
from dual
where not exists (
select resulttype
from tt_Results
where resulttype = 'first' and ID = 1)
union all
select 'second' resulttype, '0' as exists
from dual
where not exists (
select resulttype
from tt_Results
where resulttype = 'second' and ID = 1)
union all
select 'third' resulttype, '0' as exists
from dual
where not exists (
select resulttype
from tt_Results
where resulttype = 'third' and ID = 1)
) res
最终的查询结果看起来不错,但是速度很慢。有人有更好的 PL/SQL 解决方案吗?感谢您的回答!
您可以通过创建子查询来保存您感兴趣的结果类型,然后使用分区外部联接来实现此目的,如下所示:
with tt_results as (select 1 id, 'first' resulttype from dual union all
select 1 id, 'second' resulttype from dual union all
select 1 id, 'third' resulttype from dual union all
select 2 id, 'second' resulttype from dual union all
select 2 id, 'third' resulttype from dual union all
select 3 id, 'first' resulttype from dual),
dummy as (select 1 position, 'first' resulttype from dual union all
select 2 position, 'second' resulttype from dual union all
select 3 position, 'third' resulttype from dual)
select res.id,
d.resulttype,
case when res.resulttype is not null then 1 else 0 end res_exists
from dummy d
left outer join tt_results res partition by (res.id) on d.resulttype = res.resulttype
order by res.id,
d.position;
ID RESULTTYPE RES_EXISTS
---------- ---------- ----------
1 first 1
1 second 1
1 third 1
2 first 0
2 second 1
2 third 1
3 first 1
3 second 0
3 third 0
Adrian Billington 在 partititioned outer joins 上发表了一篇精彩的文章,如果您想了解更多关于它们的信息。
如果您的 tt_results table 可能包含比您感兴趣的更多的结果类型,您可以 want/need 添加一个谓词以仅从虚拟子查询中获取行,否则您可以获得所有 3 个结果类型都不存在的 ID(尽管这可能是您想要看到的)。
预计到达时间:如果您需要一次性 select 多个 ID,这将有效。
从所有类型的 table 左连接到您的 table,使用 case
根据是否进行连接来计算 exists
:
select
type,
case when resultType is null then '0' else '1' end as exists
from (select 'first' type from dual union
select 'second' from dual union
select 'third' from dual) t
left join tt_Results on resultType = type
and ID = 1
注意条件ID = 1
是join条件的一部分,not在where
子句中.
我建议为类型创建一个 3 行 table,这样查询将变得简单:
select
type,
case when resultType is null then '0' else '1' end as exists
from types
left join tt_Results on resultType = type
and ID = 1
我有一个“tt_Results”table,它恰好包含三行/ID,例如:
ID | ResultType
---------------
1 | first
1 | second
1 | third
我的查询如下:
select t.resultType
from tt_Results
where ID = 1;
通常,此查询应该return 所有三行。我的问题是,如果一行或多行不存在,我必须合并所有三个“类型”。
select res.* from
(
select resultType, '1' as exists
from tt_Results
where ID = 1
union all
select 'first' resulttype, '0' as exists
from dual
where not exists (
select resulttype
from tt_Results
where resulttype = 'first' and ID = 1)
union all
select 'second' resulttype, '0' as exists
from dual
where not exists (
select resulttype
from tt_Results
where resulttype = 'second' and ID = 1)
union all
select 'third' resulttype, '0' as exists
from dual
where not exists (
select resulttype
from tt_Results
where resulttype = 'third' and ID = 1)
) res
最终的查询结果看起来不错,但是速度很慢。有人有更好的 PL/SQL 解决方案吗?感谢您的回答!
您可以通过创建子查询来保存您感兴趣的结果类型,然后使用分区外部联接来实现此目的,如下所示:
with tt_results as (select 1 id, 'first' resulttype from dual union all
select 1 id, 'second' resulttype from dual union all
select 1 id, 'third' resulttype from dual union all
select 2 id, 'second' resulttype from dual union all
select 2 id, 'third' resulttype from dual union all
select 3 id, 'first' resulttype from dual),
dummy as (select 1 position, 'first' resulttype from dual union all
select 2 position, 'second' resulttype from dual union all
select 3 position, 'third' resulttype from dual)
select res.id,
d.resulttype,
case when res.resulttype is not null then 1 else 0 end res_exists
from dummy d
left outer join tt_results res partition by (res.id) on d.resulttype = res.resulttype
order by res.id,
d.position;
ID RESULTTYPE RES_EXISTS
---------- ---------- ----------
1 first 1
1 second 1
1 third 1
2 first 0
2 second 1
2 third 1
3 first 1
3 second 0
3 third 0
Adrian Billington 在 partititioned outer joins 上发表了一篇精彩的文章,如果您想了解更多关于它们的信息。
如果您的 tt_results table 可能包含比您感兴趣的更多的结果类型,您可以 want/need 添加一个谓词以仅从虚拟子查询中获取行,否则您可以获得所有 3 个结果类型都不存在的 ID(尽管这可能是您想要看到的)。
预计到达时间:如果您需要一次性 select 多个 ID,这将有效。
从所有类型的 table 左连接到您的 table,使用 case
根据是否进行连接来计算 exists
:
select
type,
case when resultType is null then '0' else '1' end as exists
from (select 'first' type from dual union
select 'second' from dual union
select 'third' from dual) t
left join tt_Results on resultType = type
and ID = 1
注意条件ID = 1
是join条件的一部分,not在where
子句中.
我建议为类型创建一个 3 行 table,这样查询将变得简单:
select
type,
case when resultType is null then '0' else '1' end as exists
from types
left join tt_Results on resultType = type
and ID = 1