122

Using a Microsoft version of SQL, here's my simple query. If I query a record that doesn't exist then I will get nothing returned. I'd prefer that false (0) is returned in that scenario. Looking for the simplest method to account for no records.

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
John
  • 1
  • 13
  • 98
  • 177
Matt
  • 6,264
  • 10
  • 54
  • 82

16 Answers16

153

This is similar to Adam Robinson's, but uses ISNULL instead of 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)

If the inner query has a matching row, then 1 is returned. The outer query (with ISNULL) then returns this value of 1. If the inner query has no matching row, then it doesn't return anything. The outer query treats this like a NULL, and so the ISNULL ends up returning 0.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Moe Sisko
  • 11,665
  • 8
  • 50
  • 80
  • 2
    Thank you for adding this one! It's exactly what I need, as I could just SELECT ISNULL( (SELECT Id ... instead of 1 to get the data I was looking for! – Jesse Smith Feb 02 '12 at 19:34
  • 4
    Very late, I know, but you can replace ISNULL with COALESCE to acheive the same result. – BlueChippy Jun 03 '13 at 10:21
  • 2
    I got into the habit of using COALESCE rather than ISNULL because, from memory (habits die hard), ISNULL is not available in SQL Lite or whatever it's called that runs on older Windows Mobile devices. COALESCE works on both, lite, Express and full-blown SQL. – Ads Sep 03 '14 at 02:17
  • 1
    It works better, if you want to get variable value, instead of 0 or 1. Adam's query requires grouping or something like that. – Arseniy Apr 29 '15 at 09:01
  • @MoeSisko I like how it returns the 0 if it is null, but instead of returning a 1, how can I get it to return the value from the table? – Michael Aug 10 '16 at 13:34
  • 1
    @Michael - instead of "SELECT 1", you can "SELECT S.YourRequiredColumnName". – Moe Sisko Aug 10 '16 at 23:58
  • Perfect!. And for those of you wanting to increment identity fields through an SQL query, instead of creating an autoincrement field in the DBMS, here is a nice line: SELECT ISNULL((SELECT max(id)+1 FROM YourTable), 0). If there are no rows in the table, the query inserts 0 as the identity value – netfed Sep 11 '16 at 00:06
  • i would prefer this solution because Adam's solution can only output 1 or 0 instead of some value in table 'Sites'. – Yang You Aug 27 '18 at 04:17
75
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)
Adam Robinson
  • 182,639
  • 35
  • 285
  • 343
  • Below query returns single value in else condition, but ideally it should return multiple values. select case when count(QTIB_REQ_)<1 then 0 else QTIB_REQ_ end from qb_requisitions_all where QTIB_REQ_ IN ($Req_disabled_WA) and CLIENT___BENCH___NON_BILLABLE NOT IN ( 'Non Billable', 'Non-Billable', 'NonBillable', 'Bench', 'Bench - SC Cleared Strategic Hires', 'Bench/US project') and DATEDIFF(CURDATE(),TARGET_FILL_DATE)<60 and DATEDIFF(CURDATE(),TARGET_FILL_DATE)>0 – Praneet Bahadur Aug 07 '19 at 11:47
30

This might be a dead horse, another way to return 1 row when no rows exist is to UNION another query and display results when non exist in the table.

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
) 
anAgent
  • 2,550
  • 24
  • 34
17

Something like:

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
Ellis
  • 395
  • 3
  • 8
  • I used this solution as it makes more sense to me (I'm not traditionally a SQL user), However, I am using SQL Server, I found that adding the col name to this rounded this solution nicely. i.e. after your `select 1` and `select 2` I added `as ` – Harvey Jun 17 '16 at 11:19
12

I read all the answers here, and it took a while to figure out what was going on. The following is based on the answer by Moe Sisko and some related research

If your SQL query does not return any data there is not a field with a null value so neither ISNULL nor COALESCE will work as you want them to. By using a sub query, the top level query gets a field with a null value, and both ISNULL and COALESCE will work as you want/expect them to.

My query

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

My query with comments

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'
James Jenkins
  • 1,954
  • 1
  • 24
  • 43
6

You only have to replace the WHERE with a 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

This solution allows you to return default values for each column also, for example:

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 ...
Sarsaparilla
  • 6,300
  • 1
  • 32
  • 21
6

This Might be one way.

SELECT TOP 1 [Column Name] FROM (SELECT [Column Name] FROM [table]
    WHERE [conditions]
    UNION ALL
    SELECT 0 )A ORDER BY [Column Name] DESC
Robert
  • 5,278
  • 43
  • 65
  • 115
Gopal V
  • 61
  • 1
  • 4
3

No record matched means no record returned. There's no place for the "value" of 0 to go if no records are found. You could create a crazy UNION query to do what you want but much, much, much better simply to check the number of records in the result set.

Larry Lustig
  • 49,320
  • 14
  • 110
  • 160
3
DECLARE @col int; 
select @col = id  FROM site WHERE status = 1; 
select coalesce(@col,0);
Black
  • 5,023
  • 6
  • 63
  • 92
2

@hai-phan's answer using LEFT JOIN is the key, but it might be a bit hard to follow. I had a complicated query that may also return nothing. I just simplified his answer to my need. It's easy to apply to query with many columns.

;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

Update: This answer on SqlServerCentral is the best. It utilizes this feature of MAX - "MAX returns NULL when there is no row to select."

SELECT ISNULL(MAX(value), 0) FROM table WHERE Id = @SiteId
Weihui Guo
  • 3,669
  • 5
  • 34
  • 56
1

What about WITH TIES?

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]
Fandango68
  • 4,461
  • 4
  • 39
  • 74
1

You should avoid using expensive methods. You don't need any column for TBL2.

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

Or this code:

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

You can do something just like this.

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
Rinku Choudhary
  • 1,529
  • 1
  • 13
  • 22
  • this combined with removing the `ELSE` clause was exactly what I was looking for. If rows are present, you can return a value, if not, no rows arereturned. – Duck Ling Oct 25 '22 at 08:34
0

My solition is working

can testing by change where 1=2 to 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
0

I have a union query with 6 queries. They all match off of a number in 1 table. If there is no value in one of the queries it will not show any result.

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 18 '22 at 23:38
-2

I liked James Jenkins reply with the ISNULL check, but I think he meant IFNULL. ISNULL does not have a second parameter like his syntax, but IFNULL has the second parameter after the expression being checked to substitute if a NULL is found.