【问题标题】:Need BOOLEAN Result from SQL EXISTS Statement without using a WHERE Clause需要来自 SQL EXISTS 语句的 BOOLEAN 结果而不使用 WHERE 子句
【发布时间】:2012-06-18 01:57:11
【问题描述】:

在一个简单的查询中,有什么方法可以在不使用 WHERE 子句的情况下使用 SQL EXISTS 语句返回布尔值?

所有 2008 R2 SQL Server 联机丛书示例都显示了另一个 WHERE 子句和两个表。网站示例显示过程中的 WHERE 或 IF-THEN-ELSE。

我希望在一张桌子上做以下事情:

EXISTS
(SELECT  cx.id
 FROM fdd.admissions_view as cx  
 WHERE cx.id=1111 and cx.campus='MEXI') 

SELECT 语句工作正常并返回 ID。我只想添加 EXISTS 以返回 BOOLEAN,但上面的语法无效。

我可以这样做吗?如果是这样,我在语法方面缺少什么?如果不是,还有什么其他技术可以工作?

请指教。谢谢。

【问题讨论】:

  • SQL Server 中没有布尔值。你的意思是位;-)
  • @Bridge 是 -- 布尔型(具有两种状态之一),而不是 troolean,除非它可以为空 ;-)
  • @pst 没想到FILE NOT FOUND 是吗? :P
  • @Bridge 不是特别的,没有;-)
  • @Bridge 你已经说过两次了,你的意思是什么? OP 不想要布尔数据类型,他想要表达式的布尔结果。你是说IF (1=1) 的行为不像布尔值?

标签: sql-server tsql exists


【解决方案1】:

根据 ryenus 的回答,在 MS SQL Server 上返回位结果的解决方案:

select 
    cast(
        case when exists
            (select id from fdd.admissions_view where id=1111 and campus = 'MEXI') 
        then 1 
        else 0 
        end 
    as bit) as Result

如果没有强制转换,这将返回一个 int 结果。

【讨论】:

    【解决方案2】:

    这是一个使用EXISTSCASE WHEN ... THEN .. ELSE ... END 的,用MySQL 和Oracle 测试:

    SELECT 
      CASE WHEN EXISTS 
        (SELECT  cx.id
         FROM fdd.admissions_view as cx  
         WHERE cx.id=1111 and cx.campus='MEXI')
      THEN 1 
      ELSE 0 
      END 
    FROM DUAL
    

    更新:

    找到一些相关的Q/A:

    【讨论】:

    • 这是最好的答案,可悲的是,最后和最少投票的另一个例子是最好的答案,sigh。点赞!
    • 确实是最佳答案,在 SQL Server 中,我必须添加对位的强制转换,以便在 C# 代码中使用此语句调用存储过程。
    【解决方案3】:

    问题在于EXISTS 仅在某些语法结构中是有效的语法。我不知道正式的规则(这意味着我应该去 RTFM :-?),但 EXISTS 可以包裹在 case 中,这将在用作表达式时起作用

    set @r = case when exists (...) then 1 else 0 end
    
    return case when exists (...) then 1 else 0 end
    

    例如

    return case when exists (SELECT 1 -- because it's as good as anything else
        FROM fdd.admissions_view as cx  
        WHERE cx.id=1111 and cx.campus='MEXI')
      then 1 else 0 end
    

    【讨论】:

    • 您的第一条声明本身是无效的 (case when exists ...)。我建议删除或改进它,否则你会无意中暗示case 是一个语句,而不是一个表达式,并且可能能够像在其他语言中那样确定流的控制,这是很多更环保的用户所假设的T-SQL 也是如此。
    • @AaronBertrand 感谢您的建议。当我写它时,我在想“在一个表达式中”,但你是对的,因为它可能会产生误导。
    【解决方案4】:

    不完全确定您所说的“返回”是什么意思,但这里有一些想法。

    DECLARE @return BIT = 0;
    IF EXISTS( SELECT  cx.id
        FROM fdd.admissions_view as cx  
        WHERE cx.id=1111 and cx.campus='MEXI' ) SET @return = 1;
    

    或者:

    IF EXISTS( SELECT  cx.id
        FROM fdd.admissions_view as cx  
        WHERE cx.id=1111 and cx.campus='MEXI' ) SELECT 1 AS returnValue
    

    【讨论】:

      【解决方案5】:

      怎么样

      select case when count(cx.id) > 0 then 1 else 0 end 
       FROM fdd.admissions_view as cx  
       WHERE cx.id=1111 and cx.campus='MEXI'
      

      ?

      【讨论】:

      • 我想知道SQL Server是否足够聪明,在count(...) > 0找到一条记录后停止;例如如果在内部重写。 (在这种情况下,它可能不能超过 1,但是...)
      • @pst 我认为你不应该期待这种优化,或者即使在某些情况下你观察到它(或认为你观察到它)也要依赖它。我认为 EXISTS 永远不会比 COUNT 差,但通常会更好。因此,除非实际计数相关,否则我每次都会选择 EXISTS。
      • @AaronBertrand 我同意,主要是因为我认为它在语义上更清晰——但它仍然是值得深思的有趣的东西。我发现现代关系数据库“非常快速地做正确的事情”的能力非常惊人。
      • @pst meh,为什么?如果EXISTS 总是一样快或更快,为什么不总是使用EXISTS 并假装COUNT 不是一个选项,除非在您不只是在寻找开/关指示器的情况下?
      猜你喜欢
      • 1970-01-01
      • 2013-04-17
      • 1970-01-01
      • 1970-01-01
      • 2020-01-28
      • 1970-01-01
      • 2017-11-19
      • 1970-01-01
      • 2019-06-28
      相关资源
      最近更新 更多