简体   繁体   English

Oracle SQL:如何将 distinct 替换为 where exists

[英]Oracle SQL: How to replace distinct with where exists

I've read that using a where exists clause could usually be more efficient than writing select distinct.我读过使用 where exists 子句通常比写 select distinct 更有效。 How could I rewrite the below 2 queries using the where exists condition?如何使用 where exists 条件重写以下 2 个查询? Not sure if query2 is eligible for this clause or this only applies to joins.不确定 query2 是否符合此子句的条件,或者这仅适用于联接。

Query 1:查询一:

SELECT DISTINCT
    e.field1,
    regexp_substr(substr(TRIM(d.field2), 1, 2), '[A-Za-z]+', 1, 1) postal_group
FROM
    table1   e
    JOIN table1   f ON f.field0 = e.field0
    JOIN table2   g ON g.field3 = f.field3
    JOIN table3   g ON g.field4 = f.field4
    JOIN table4   a ON a.field5 = g.field5
    JOIN table5   b ON ( b.field6 = a.field6
                       AND b.field7 = a.field7 )
    JOIN table6   c ON ( c.field8 = b.field8
                       AND c.field9 = b.field9 )
    JOIN table7   d ON ( d.field10 = c.field10
                       AND d.field11 = c.field11 )

Query 2:查询 2:

SELECT DISTINCT
    field
FROM
    table1
WHERE
    condition = 'value'

For your second query you can use group by clause to avoid DISTINCT .对于第二个查询,您可以使用group by clause来避免DISTINCT

SELECT field
FROM
    table1
WHERE
    condition = 'value'
Group by field

Please try below query with where exists instead of Distinct:请尝试使用 where exists 而不是 Distinct 进行以下查询:

SELECT 
    e.field1,
    regexp_substr(substr(TRIM(d.field2), 1, 2), '[A-Za-z]+', 1, 1) postal_group
FROM
    table1   e
    where exists 
    (
        select 1 from table1   f 
        JOIN table2   g ON g.field3 = f.field3
        JOIN table3   g ON g.field4 = f.field4
        JOIN table4   a ON a.field5 = g.field5
        JOIN table5   b ON ( b.field6 = a.field6
                           AND b.field7 = a.field7 )
        JOIN table6   c ON ( c.field8 = b.field8
                           AND c.field9 = b.field9 )
        JOIN table7   d ON ( d.field10 = c.field10
                           AND d.field11 = c.field11 )
        where f.field0 = e.field0
    )

You can't avoid a join with d because you need a column from it.您无法避免与d连接,因为您需要其中的一列。 Therefore the best you can do is:因此,您能做的最好的事情是:

select e.column1
     , d.column2 as postal_group
from   table1 e
       join table7 d
            on  d.column10 = c.column10
            and d.column11 = c.column11
where  exists
       ( select 1 from table1 f
                join table2 g on g.column3 = f.column3
                join table3 h on h.column4 = f.column4
                join table4 a on a.column5 = h.column5
                join table5 b on b.column6 = a.column6 and b.column7 = a.column7
                join table6 c on c.column8 = b.column8 and c.column9 = b.column9
         where  f.column0 = e.column0 );

You only need distinct if table7.column2 can have duplicate values for a (column10, column11) combination.如果 table7.column2 可以具有(column10, column11)组合的重复值,则仅需要distinct

This may or may not be more efficient than the original version - compare timings, execution plans, reads etc.这可能会或可能不会比原始版本更有效 - 比较时间、执行计划、读取等。

(I've renamed 'fields' as columns because that's what tables have. Also there are no brackets in a join clause and adding them tends to confuse code formatters.) (我已将“字段”重命名为列,因为这就是表所具有的。在join子句中也没有括号,添加它们往往会混淆代码格式化程序。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM