[英]Oracle How to simplify a select count(*) from (subquery)?
我被要求尝试简化count()
查询,但是我不知道从哪里开始,查询是这样的:
SELECT COUNT( 1 )
FROM (
SELECT DISTINCT a.col,b.colx,c.coly
FROM a
JOIN b on a.id = b.id
JOIN c on b.id = c.id
WHERE a.xyz = 'something'
AND b.hijk = 'something else'
AND c.id IN (
SELECT cid
FROM cwa
WHERE csid = 22921
)
ORDER BY
e.create_timestamp DESC
);
有人告诉我可以简化SELECT COUNT(1) FROM (subquery)
,这怎么做?
我已经尝试了几件事,但是结果与上面的查询不同。
除非您在rownum上过滤结果,否则子查询中的order-by
不会有用(有时会出错,具体取决于上下文)。 您可以用联接替换内部子查询:
SELECT COUNT(*)
FROM (
SELECT DISTINCT a.col,b.colx,c.coly
FROM a
JOIN b on a.id = b.id
JOIN c on b.id = c.id
JOIN cwa on c.id cwa.cid
WHERE a.xyz = 'something'
AND b.hijk = 'something else'
AND cwa.csid = 22921
);
如果您可以识别出您选择的三列中没有出现的字符,甚至可以不使用子查询就可以做到这一点,因此您可以将其用作分隔符。 例如,如果您永远不会出现波浪号,则可以执行以下操作:
SELECT COUNT(DISTINCT a.col ||'~'|| b.colx ||'~'|| c.coly)
FROM a
JOIN b on a.id = b.id
JOIN c on b.id = c.id
JOIN cwa on c.id cwa.cid
WHERE a.xyz = 'something'
AND b.hijk = 'something else'
AND cwa.csid = 22921;
尽管这是更简单还是更清晰是一个意见问题。
由于count()
仅接受单个参数,并且您希望计算这三列的(不同的)组合,因此该机制将所有三个列连接为一个字符串,然后计算该字符串的出现次数。 添加了定界符,以便您可以区分歧义的列值,例如在CTE中使用人为的示例:
with cte (col1, col2) as (
select 'The', 'search' from dual
union all select 'These', 'arch' from dual
)
select col1, col2,
col1 || col2 as bad,
col1 ||'~'|| col2 as good
from cte;
COL1 COL2 BAD GOOD
----- ------ ----------- ------------
The search Thesearch The~search
These arch Thesearch These~arch
通过简单的“坏”串联,两行看起来是相同的。 通过添加定界符以制作“好”版本,您仍然可以区分它们,因此计算不同的串联值可获得正确的答案:
with cte (col1, col2) as (
select 'The', 'search' from dual
union all select 'These', 'arch' from dual
)
select count(distinct col1 || col2) as bad_count,
count (distinct col1 ||'~'|| col2) as good_count
from cte;
BAD_COUNT GOOD_COUNT
---------- ----------
1 2
如果col1
以波浪号结尾,或者col2
以波浪号开头,您将回到歧义:
with cte (col1, col2) as (
select 'The~', 'search' from dual
union all select 'The', '~search' from dual
)
select col1, col2,
col1 || col2 as bad,
col1 ||'~'|| col2 as still_bad
from cte;
COL1 COL2 BAD STILL_BAD
---- ------- ----------- ------------
The~ search The~search The~~search
The ~search The~search The~~search
因此分隔符必须是在任何值中都找不到的东西。
尝试使用
SELECT count(DISTINCT a.col)
FROM a
JOIN b on a.id = b.id
JOIN c on b.id = c.id
WHERE a.xyz = 'something'
AND b.hijk = 'something else'
AND c.id IN (
SELECT cid
FROM cwa
WHERE csid = 22921
);
因为order by会增加您不必要的执行时间
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.