【问题标题】:Return Boolean Value on SQL Select Statement在 SQL Select 语句上返回布尔值
【发布时间】:2012-05-09 19:18:11
【问题描述】:

如何在 SQL Select 语句中返回布尔值?

我试过这段代码:

SELECT CAST(1 AS BIT) AS Expr1
FROM [User]
WHERE (UserID = 20070022)

如果UserID 存在于表中,它只会返回TRUE。如果桌子上不存在UserID,我希望它返回FALSE

【问题讨论】:

  • 哪个 dbms? sql的细节不同。
  • SQL Server 不支持布尔类型,例如SELECT WHEN CAST(1 AS BIT) THEN 'YES' END AS result -- 导致错误,即CAST(1 AS BIT) 不是同一个逻辑 TRUE。

标签: sql select boolean


【解决方案1】:

如果用户不存在,您所拥有的将不会返回任何行。这是您需要的:

SELECT CASE WHEN EXISTS (
    SELECT *
    FROM [User]
    WHERE UserID = 20070022
)
THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT) END

【讨论】:

  • 为什么要用星号,最好用1而不是*
  • @robertpeter07 - 两者是等价的,但 * 更惯用。见this question
  • 如果在 WHILE 循环中使用,我是否必须将其括在大括号 {} 中,紧跟在“WHILE”之后?
  • 能否给返回值加个列名?
  • @xMetalDetectorx 这对我来说添加了列名(AS bool 部分非常重要):CAST( CASE WHEN EXISTS ( SELECT * FROM mytable WHERE mytable.id = 1) THEN TRUE ELSE FALSE END AS bool) AS nameofmycolumn
【解决方案2】:

可能是这样的:

SELECT CAST(CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END AS BIT)
FROM dummy WHERE id = 1;

http://sqlfiddle.com/#!3/5e555/1

【讨论】:

  • 这会返回一个字符串,而不是一个布尔值
  • 最好包含列名 - SELECT CAST(CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END AS BIT) as mycolumnname FROM dummy WHERE id = 1
【解决方案3】:

鉴于通常1 = true0 = false,您只需计算行数,然后转换为boolean

因此,您发布的代码只需要添加一个COUNT() 函数:

SELECT CAST(COUNT(1) AS BIT) AS Expr1
FROM [User]
WHERE (UserID = 20070022)

【讨论】:

  • 对包含大量行的表执行Exists( 测试比执行Count(1) 测试要快得多。
  • 可能。我在回答中没有声称性能,只是为了实现 OP 想要的最小代码更改。但是,如果列 UserID 被索引(或者甚至是 PK),那么您肯定会直接进入存在(或不存在)的唯一行。
【解决方案4】:

使用返回 0 或 1 的“存在​​”。

查询将是这样的:

SELECT EXISTS(SELECT * FROM USER WHERE UserID = 20070022)

【讨论】:

  • 错误:“关键字'EXISTS'附近的语法不正确。” sqlfiddle.com/#!18/ef905/18
  • 在这种情况下SELECT 1 会比SELECT * 快​​吗?
【解决方案5】:
select CAST(COUNT(*) AS BIT) FROM [User] WHERE (UserID = 20070022)

如果 count(*) = 0 返回 false。如果 count(*) > 0 返回 true。

【讨论】:

    【解决方案6】:

    我是这样做的:

    SELECT 1 FROM [dbo].[User] WHERE UserID = 20070022
    

    因为布尔值永远不能为空(至少在 .NET 中),它应该默认为 false,或者如果它默认为 true,您可以自己设置它。但是 1 = true,所以 null = false,并且没有额外的语法。

    注意:我使用 Dapper 作为我的 micro orm,我想 ADO 应该也可以工作。

    【讨论】:

    • 到目前为止我最喜欢的,最简洁的答案。所有答案的小提琴:sqlfiddle.com/#!18/ef905/18
    • “布尔值永远不能为空(至少在 .NET 中)。” (bool?) 是一个可以为空的 bool。
    【解决方案7】:

    对于那些有兴趣获得添加自定义列名称的价值的人,这对我有用:

    CAST(
        CASE WHEN EXISTS ( 
               SELECT * 
               FROM mytable 
               WHERE mytable.id = 1
        ) 
        THEN TRUE 
        ELSE FALSE 
        END AS bool) 
    AS "nameOfMyColumn"
    

    如果您对保持名称的大小写不感兴趣(在某些客户端中),您可以跳过列名称中的双引号。

    我稍微调整了@Chad 对此的回答。

    【讨论】:

    • Msg 102,级别 15,状态 1,第 8 行“CAST”附近的语法不正确。消息 156,级别 15,状态 1,第 12 行关键字“THEN”附近的语法不正确。
    • @ShaneC 我在 PostgreSQL 9.X 上测试了这段代码,它运行良好。你用的是什么服务器?
    【解决方案8】:

    注意另一个等效问题:创建一个 SQL 查询,如果条件满足则返回 (1),否则返回空结果。请注意,此问题的解决方案更通用,并且可以轻松地与上述答案一起使用以实现您提出的问题。由于这个问题更普遍,除了上面为您的问题提供的漂亮解决方案之外,我正在证明它的解决方案。

    SELECT DISTINCT 1 AS Expr1
    FROM [User]
    WHERE (UserID = 20070022)
    

    【讨论】:

      【解决方案9】:
      DECLARE @isAvailable      BIT = 0;
      
      IF EXISTS(SELECT 1  FROM [User] WHERE (UserID = 20070022))
      BEGIN
       SET @isAvailable = 1
      END
      

      最初isAvailable布尔值设置为0

      【讨论】:

        猜你喜欢
        • 2012-08-16
        • 1970-01-01
        • 2011-12-08
        • 2015-05-03
        • 1970-01-01
        • 1970-01-01
        • 2014-12-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多