【问题标题】:Return a value if no rows are found in Microsoft tSQL如果在 Microsoft SQL 中未找到任何行,则返回一个值
【发布时间】:2010-04-21 02:10:12
【问题描述】:

使用 Microsoft 版本的 SQL,这是我的简单查询。如果我查询一条不存在的记录,那么我将不会得到任何返回。我希望在那种情况下返回 false (0)。寻找最简单的方法来解释没有记录。

SELECT  CASE
            WHEN S.Id IS NOT NULL AND S.Status = 1 AND (S.WebUserId = @WebUserId OR S.AllowUploads = 1) THEN 1
            ELSE 0
        END AS [Value]

        FROM Sites S

        WHERE S.Id = @SiteId

【问题讨论】:

    标签: tsql


    【解决方案1】:

    这类似于 Adam Robinson 的,但使用 ISNULL 而不是 COUNT。

    SELECT ISNULL(
    (SELECT 1 FROM Sites S
    WHERE S.Id = @SiteId and S.Status = 1 AND 
          (S.WebUserId = @WebUserId OR S.AllowUploads = 1)), 0)
    

    如果内部查询有匹配的行,则返回 1。外部查询(使用 ISNULL)然后返回此值 1。如果内部查询没有匹配的行,则它不返回任何内容。外部查询将此视为 NULL,因此 ISNULL 最终返回 0。

    【讨论】:

    • 感谢您添加这个!这正是我所需要的,因为我可以 SELECT ISNULL((SELECT Id ... 而不是 1 来获取我正在寻找的数据!
    • 很晚了,我知道,但是你可以用 COALESCE 替换 ISNULL 来达到同样的结果。
    • 我养成了使用 COALESCE 而不是 ISNULL 的习惯,因为从记忆中(习惯很难改掉),ISNULL 在 SQL Lite 或在旧版 Windows Mobile 设备上运行的任何其他设备中不可用。 COALESCE 适用于 lite、Express 和成熟的 SQL。
    • 如果你想获得变量值而不是 0 或 1,它会更好。亚当的查询需要分组或类似的东西。
    • @MoeSisko 我喜欢它在为空时返回 0 的方式,但不是返回 1,而是如何让它从表中返回值?
    【解决方案2】:
    SELECT CASE WHEN COUNT(1) > 0 THEN 1 ELSE 0 END AS [Value]
    
    FROM Sites S
    
    WHERE S.Id = @SiteId and S.Status = 1 AND 
          (S.WebUserId = @WebUserId OR S.AllowUploads = 1)
    

    【讨论】:

    • 以下查询在 else 条件下返回单个值,但理想情况下它应该返回多个值。选择 count(QTIB_REQ_)0
    【解决方案3】:

    这可能是一匹死马,当不存在行时返回 1 行的另一种方法是 UNION 另一个查询并在表中不存在时显示结果。

    SELECT S.Status, COUNT(s.id) AS StatusCount
    FROM Sites S
    WHERE S.Id = @SiteId
    GROUP BY s.Status
    UNION ALL --UNION BACK ON TABLE WITH NOT EXISTS
    SELECT 'N/A' AS Status, 0 AS StatusCount
    WHERE NOT EXISTS (SELECT 1
       FROM Sites S
       WHERE S.Id = @SiteId
    ) 
    

    【讨论】:

    • 我在尝试从查询中获取总计时使用了类似的方法。我只是做了一个返回 0 (SELECT 0) 的查询的联合,然后我在联合上做了一个 SUM。简单易懂。
    • 如果返回2行,是否保证这些行会按照预期的顺序返回?
    • 而且执行计划很繁重
    【解决方案4】:

    类似:

    if exists (select top 1 * from Sites S where S.Id IS NOT NULL AND S.Status = 1 AND (S.WebUserId = @WebUserId OR S.AllowUploads = 1))
        select 1
    else
        select 0
    

    【讨论】:

    • 我使用了这个解决方案,因为它对我来说更有意义(我不是传统的 SQL 用户),但是,我使用的是 SQL Server,我发现将 col 名称添加到这个解决方案中很好。即在您的select 1select 2 之后,我添加了as <colName>
    【解决方案5】:

    我在这里阅读了所有答案,但花了一段时间才弄清楚发生了什么。以下是基于Moe Sisko的回答和一些相关研究

    如果您的 SQL 查询不返回任何数据,则不存在具有空值的字段,因此 ISNULL 和 COALESCE 都不会像您希望的那样工作。通过使用子查询,顶级查询获得一个具有空值的字段,并且 ISNULL 和 COALESCE 都将按照您的需要/预期工作。

    我的查询

    select isnull(
     (select ASSIGNMENTM1.NAME
     from dbo.ASSIGNMENTM1
     where ASSIGNMENTM1.NAME = ?)
    , 'Nothing Found') as 'ASSIGNMENTM1.NAME'
    

    我对 cme​​ts 的查询

    select isnull(
    --sub query either returns a value or returns nothing (no value)
     (select ASSIGNMENTM1.NAME
     from dbo.ASSIGNMENTM1
     where ASSIGNMENTM1.NAME = ?)
     --If there is a value it is displayed 
     --If no value, it is perceived as a field with a null value, 
     --so the isnull function can give the desired results
    , 'Nothing Found') as 'ASSIGNMENTM1.NAME'
    

    【讨论】:

      【解决方案6】:

      您只需将 WHERE 替换为 LEFT JOIN:

      SELECT  CASE
              WHEN S.Id IS NOT NULL AND S.Status = 1 AND ...) THEN 1
              ELSE 0
          END AS [Value]
      
          FROM (SELECT @SiteId AS Id) R
          LEFT JOIN Sites S ON S.Id = R.Id
      

      此解决方案还允许您为每列返回默认值,例如:

      SELECT
          CASE WHEN S.Id IS NULL THEN 0 ELSE S.Col1 END AS Col1,
          S.Col2,
          ISNULL(S.Col3, 0) AS Col3
      FROM
          (SELECT @Id AS Id) R
          LEFT JOIN Sites S ON S.Id = R.Id AND S.Status = 1 AND ...
      

      【讨论】:

        【解决方案7】:

        这可能是一种方式。

        SELECT TOP 1 [Column Name] FROM (SELECT [Column Name] FROM [table]
            WHERE [conditions]
            UNION ALL
            SELECT 0 )A ORDER BY [Column Name] DESC
        

        【讨论】:

        • 我喜欢这种方法。我觉得在表达默认数据时更简洁一些,尤其是当您最终得到大量数据/默认值列时。
        • 大声笑这是最好和最干净的解决方案
        【解决方案8】:

        没有匹配的记录意味着没有返回记录。如果没有找到记录,则 0 的“值”将无处可去。您可以创建一个疯狂的 UNION 查询来做您想做的事情,但要检查结果集中的记录数要好得多。

        【讨论】:

        • 目前,这就是我所做的。检查记录计数是否为空。认为它们可能是一种快捷方式。
        • 某些应用程序不允许您“简单地”检查
        【解决方案9】:
        DECLARE @col int; 
        select @col = id  FROM site WHERE status = 1; 
        select coalesce(@col,0);
        

        【讨论】:

          【解决方案10】:

          有关系呢?

          SELECT TOP 1 WITH TIES tbl1.* FROM 
                  (SELECT CASE WHEN S.Id IS NOT NULL AND S.Status = 1 
                                AND (S.WebUserId = @WebUserId OR 
                                     S.AllowUploads = 1)
                               THEN 1 
                               ELSE 0 AS [Value]
                   FROM Sites S
                   WHERE S.Id = @SiteId) as tbl1
          ORDER BY tbl1.[Value]
          

          【讨论】:

            【解决方案11】:

            @hai-phan 使用LEFT JOIN 的答案是关键,但可能有点难以理解。我有一个复杂的查询,也可能什么也不返回。我只是简化了他对我需要的回答。很容易应用于多列查询。

            ;WITH CTE AS (
              -- SELECT S.Id, ...
              -- FROM Sites S WHERE Id = @SiteId
              -- EXCEPT SOME CONDITION.
              -- Whatever your query is
            )
            SELECT CTE.* -- If you want something else instead of NULL, use COALESCE.
            FROM (SELECT @SiteId AS ID) R
            LEFT JOIN CTE ON CTE.Id = R.ID
            

            更新:This answer on SqlServerCentral 是最好的。它利用了 MAX 的这个特性 - "MAX returns NULL when there is no row to select."

            SELECT ISNULL(MAX(value), 0) FROM table WHERE Id = @SiteId
            

            【讨论】:

              【解决方案12】:

              您应该避免使用昂贵的方法。 TBL2 不需要任何列。

              SELECT COUNT(*) FROM(
                       SELECT TOP 1     1 AS CNT  FROM  TBL1 
                       WHERE ColumnValue ='FooDoo') AS TBL2
              

              或者这个代码:

              IF EXISTS (SELECT TOP 1 1 FROM TABLE1 AS T1 
                                        WHERE T1.ColumnValue='VooDoo') 
                 SELECT 1 
              ELSE 
                 SELECT 0
               
              

              【讨论】:

                【解决方案13】:

                你可以这样做。

                IF EXISTS ( SELECT * FROM TableName WHERE Column=colval)
                BEGIN
                   select 
                select name ,Id from TableName WHERE Column=colval
                END
                ELSE
                  SELECT 'test' as name,0 as Id
                

                【讨论】:

                  【解决方案14】:

                  我的解决方案正在工作

                  可以通过将 where 1=2 更改为 where 1=1 进行测试

                  select * from (
                      select col_x,case when count(1) over (partition by 1) =1 then 1 else HIDE end as HIDE from (
                      select 'test' col_x,1 as HIDE
                      where 1=2
                      union 
                      select 'if no rows write here that you want' as col_x,0 as HIDE
                      ) a
                      ) b where HIDE=1
                  

                  【讨论】:

                    【解决方案15】:

                    我喜欢 James Jenkins 对 ISNULL 检查的回复,但我认为他的意思是 IFNULL。 ISNULL 没有像他的语法那样的第二个参数,但是 IFNULL 在检查表达式之后有第二个参数,以便在找到 NULL 时进行替换。

                    【讨论】:

                    • 勉强算是一个答案,你可以把它作为评论。
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-02-25
                    • 1970-01-01
                    • 2019-04-12
                    • 2011-12-27
                    • 2021-05-19
                    • 1970-01-01
                    相关资源
                    最近更新 更多