【问题标题】:(Oracle) SQL: Column must contain a list of values(Oracle) SQL:列必须包含值列表
【发布时间】:2018-05-22 15:19:00
【问题描述】:

我正在尝试找出一个有效的 (Oracle) SQL 语句来验证一列是否至少包含一次特定的值列表。

一种选择是过滤该列表,输出所有不同的值,然后对它们进行计数。所以,是这样的:

SELECT count(*)
FROM (
      SELECT DISTINCT columnname
      FROM table
      WHERE columnname in ('a', 'b', 'c')
     ) 
;

(然后检查count(*)是否返回数字3)

这样做的问题是 DISTINCT 语句会查看整个表,这在性能方面非常糟糕。我的列表的所有三个值都可能在最开始,所以我不需要查看数百万其他行。我只想知道该列包含'a','b'和'c'。

有没有人想办法有效地解决这个问题?

提前致谢!

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    单独查找每个值可能更有效:

    select (case when exists (select 1 from t where col = 'a') and
                      exists (select 1 from t where col = 'b') and
                      exists (select 1 from t where col = 'c')
                 then 1 else 0
            end) as has_all_three_flag
    from dual;
    

    这会更好,特别是在t(col) 上的索引。

    【讨论】:

      【解决方案2】:

      如果你想摆脱 distinct,那么试试下面的,Group by 比 distinct 有更好的性能,See here

      SELECT count(*)
      FROM (
            SELECT columnname
            FROM table
            WHERE columnname in ('a', 'b', 'c')
            GROUP BY columnname
           ) 
      ;
      

      或者你可以避免使用子查询

      SELECT count(DISTINCT columnname)
            FROM table
            WHERE columnname in ('a', 'b', 'c');
      

      【讨论】:

      • 此查询仍然必须读取表中的所有行,而 Gordon 的答案使用索引最多选择 3 行。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-05
      • 2017-12-13
      • 1970-01-01
      • 2016-11-30
      • 1970-01-01
      相关资源
      最近更新 更多