如果在Microsoft tSQL中找不到行,则返回一个值


94

使用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

Answers:


64
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 _)<1然后为0的情况,否则QTIB_REQ_从qb_requisitions_all结尾,其中QTIB_REQ_ IN($ Req_disabled_WA)和CLIENT___BENCH___NON_BILLABLE NOT IN('Non Billable','Non-Billable','NonBill- SC清除了战略招聘”,“基准/美国项目”和DATEDIFF(CURDATE(),TARGET_FILL_DATE)<60和DATEDIFF(CURDATE(),TARGET_FILL_DATE)> 0
Praneet Bahadur

121

这类似于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。


2
感谢您添加此内容!这正是我所需要的,因为我可以选择SELECT ISNULL((SELECT Id ...而不是1来获取我想要的数据!
Jesse Smith

3
我知道很晚了,但是您可以用COALESCE替换ISNULL以达到相同的结果。
BlueChippy 2013年

2
我养成了使用COALESCE而不是ISNULL的习惯,因为从内存(习惯死去)来看,ISNULL在SQL Lite或在较旧的Windows Mobile设备上运行的任何东西都不可用。COALESCE适用于lite,Express和成熟的SQL。
2014年

1
如果要获取变量值而不是0或1,它会更好。Adam的查询需要分组或类似的方法。
Drac 2015年

@MoeSisko我喜欢如果它为null时如何返回0,但不是返回1,如何获取它以从表中返回值?
迈克尔,

21

这可能是一匹老马,当不存在任何行时返回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
) 

2
尝试从查询中获取总计时,我使用了类似的方法。我只是对返回0(SELECT 0)的查询进行了联合,然后SUM对联合做了a 。简单易懂。
cjbarth 2012年

2
如果返回2行,是否可以保证按预期顺序返回行?
Sarsaparilla

执行计划很繁重
Fandango68

12

就像是:

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>
Harvey

8

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

如果您的SQL查询不返回任何数据,则不存在具有null值的字段,因此ISNULL和COALESCE均无法按您希望的那样工作。通过使用子查询,顶级查询将获得一个具有空值的字段,并且ISNULL和COALESCE均可按您希望/期望的方式工作。

我的查询

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

我的查询与评论

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'

5

您只需要用LEFT JOIN替换WHERE:

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 ...

4

没有匹配的记录意味着没有记录返回。如果未找到任何记录,则“ 0”的值无处可走。您可以创建一个疯狂的UNION查询来执行所需的操作,但是只需检查结果集中的记录数,就可以做得更好。


目前,这就是我要做的。检查记录计数是否为空。认为它们可能是简化我的支票的一种方式。
马特2010年

某些应用程序不允许您“简单”检查
Nadia Solovyeva

3

这可能是一种方式。

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

我喜欢这种方法。我认为在表达默认数据时,它会更干净一些,尤其是当您最终获得大量的数据/默认值列时。
标记在斜坡

大声笑,这是最好,最干净的解决方案
凯尔·布​​莱恩斯汀

1

带领带呢?

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]

1
DECLARE @col int; 
select @col = id  FROM site WHERE status = 1; 
select coalesce(@col,0);

0

@ 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

更新:SqlServerCentral上的此答案是最好的。它利用了MAX的这一特性- “当没有可供选择的行时,MAX返回NULL”。

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

0
You should avoid using expensive methods. You dont need any column for TBL2. 

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

or

IF EXISTS (SELECT TOP 1 1 FROM TABLE1 AS T1 
                          WHERE T1.ColumnValue='VooDoo') 
   SELECT 1 
ELSE 
   SELECT 0
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.