【问题标题】:How to do EXISTS select in ANSI SQL如何在 ANSI SQL 中进行 EXISTS 选择
【发布时间】:2011-05-22 15:24:20
【问题描述】:

是否有一种跨数据库(至少是 SQL Server、Oracle、Postgre、MySQL、SQLite)的方式来执行我在 T-SQL 中使用的操作

SELECT 1 WHERE EXISTS (SELECT * FROM Foo WHERE Bar = 'Quux')

这似乎不是有效的 ANSI SQL 语法,因为没有 FROM 子句。目前我正在使用 COUNT(*) 来执行此操作,但我认为这不是最佳选择。

【问题讨论】:

    标签: sql ansi-sql


    【解决方案1】:

    子查询是不必要的 - 使用:

    SELECT DISTINCT 
           1 
      FROM Foo 
     WHERE Bar = 'Quux'
    

    一个更复杂的版本,使用聚合和 CASE 表达式:

    SELECT CASE
             WHEN COUNT(*) >= 1 THEN 1 
             ELSE 0
           END
      FROM Foo 
     WHERE Bar = 'Quux'
    

    【讨论】:

    • 我想知道为什么不使用limit,而不是distinct?不是兼容ABSI吗? SELECT 1 FROM WHERE Bar = 'Quux' LIMIT 1;
    • @andrii 不幸的是,LIMIT 不兼容 ANSI。从 SQL2008 开始,我们拥有“仅 FETCH FIRST n ROWS”和窗口聚合函数的优势,但只有少数数据库引擎支持它们。 LIMIT 也与 DISTINCT 完全不同。我们知道这里所有的元组都是相同的,因此返回带有 DISTINCT 的单行结果。此处无需人为中断结果集。
    【解决方案2】:

    有点作弊,但这应该可行,除了最愚蠢的 DBMS 之外,其他所有人都应该对 DISTINCT 1 FROM Foo 进行微不足道的优化!

    SELECT DISTINCT 1 FROM Foo WHERE EXISTS (SELECT * FROM Foo WHERE Bar = 'Quux')

    【讨论】:

      【解决方案3】:

      在您需要之前使用 COUNT。假设对 Bar 和 index 具有良好的选择性,它不会太重要,但会更易读

      SELECT COUNT(Bar) FROM Foo WHERE Bar = 'Quux'
      

      当然,您会用优化换取可移植性,所以在这种情况下使用 COUNT

      【讨论】:

      • 我正在开发一个通用库,所以我想要最佳和便携的最佳组合。还有一块饼干! :)
      猜你喜欢
      • 1970-01-01
      • 2022-11-22
      • 2017-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      相关资源
      最近更新 更多