我可以替换此oracle查询中的子查询以提高性能吗?
我需要根据查询区分1个或多个计数。因此,如果计数为1,则显示该值,否则显示计数(或者在这种情况下,为2表示它大于1,因为确切的数字是无关的)。
select t.refnum,
case count(t.acctnum)
when 1 then
( select to_number(a.acctnum)
from transactions a
where a.refnum = t.refnum)
else 2
end as num_accts
from transactions t
group by t.refnum;
REFNUM NUM_ACCTS
FF000001235 2
FF000001234 123400
FF000001236 456789
输出正确,我只需要提高性能。 Fiddle
编辑:输入
REFNUM ACCTNUM
FF000001234 123400
FF000001234 123400
我需要它将其视为1条记录,就好像group by refnum, acctnum
答案 0 :(得分:1)
您可以在子查询中使用分析计数,因此您只需按一次表格:
select refnum,
case when num_accts = 1 then to_number(acctnum) else 2 end as num_accts
from (
select refnum,
acctnum,
count(acctnum) over (partition by refnum) as num_accts,
row_number() over (partition by refnum order by null) as refnum_row
from transactions
)
where refnum_row = 1
order by refnum, refnum_row;
REFNUM NUM_ACCTS
----------- ----------
FF000001234 123400
FF000001235 2
FF000001236 456789
SQL Fiddle也显示子查询的结果集。构成基表的每一行都由其返回num_accts
列,每列具有相同的值refnum
。由于您只希望每refnum
看到一个结果,因此还有另一个额外的列,在每个refnum
中为每行分配行号,而外部查询仅查看第一行。这相当于在外部查询中只有distinct
。
在这种情况下,refnum
内的帐户顺序无关紧要,因为如果只有一个帐户,则只使用实际值;通常order by
子句中的over
会更有意义......
如果acctnum
中的单个refnum
有多行,并且您希望将其视为一个,则可以在distinct
子句中添加count()
:
count(distinct acctnum) over (partition by refnum) as num_accts,
......即:
select refnum,
case when num_accts = 1 then to_number(acctnum) else 2 end as num_accts
from (
select refnum,
acctnum,
count(distinct acctnum) over (partition by refnum) as num_accts,
row_number() over (partition by refnum order by null) as refnum_row
from transactions
)
where refnum_row = 1
order by refnum, refnum_row;
SQL Fiddle包含重复的FF000001234
和123400
示例。