Microsoft tSQL에 행이 없으면 값을 반환합니다.


97

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

답변:


66
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 then 0 else QTIB_REQ_ end from qb_requisitions_all 여기서 QTIB_REQ_ IN ($ Req_disabled_WA) 및 CLIENT___BENCH___NON_BILLABLE NOT IN ( '청구 불가', '청구 불가', '청구 불가', '청구 불가', SC는 Strategic Hires ','Bench / US project ') 및 DATEDIFF (CURDATE (), TARGET_FILL_DATE) <60 및 DATEDIFF (CURDATE (), TARGET_FILL_DATE)> 0
Praneet Bahadur

125

이것은 Adam Robinson과 유사하지만 COUNT 대신 ISNULL을 사용합니다.

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
이것을 추가 해주셔서 감사합니다! ! 내가 그냥 ISNULL ((SELECT ID를 선택 할 수 나는 데이터가 내가 찾던 얻을 대신 1 ..., 필요한 정확히
제시 스미스

3
매우 늦었습니다.하지만 ISNULL을 COALESCE로 대체하여 동일한 결과를 얻을 수 있습니다.
BlueChippy 2013-06-03

2
ISNULL이 아닌 COALESCE를 사용하는 습관이 생겼습니다. 왜냐하면 메모리에서 (열심히 죽어가는) ISNULL은 SQL Lite 또는 이전 Windows Mobile 장치에서 실행되는 이름에서 사용할 수 없기 때문입니다. COALESCE는 라이트, 익스프레스 및 본격적인 SQL 모두에서 작동합니다.
광고

1
0 또는 1 대신 변수 값을 얻으려면 더 잘 작동합니다. Adam의 쿼리에는 그룹화 또는 이와 유사한 것이 필요합니다.
Drac

@MoeSisko null이면 0을 반환하는 방법이 마음에 들지만 1을 반환하는 대신 테이블에서 값을 반환하려면 어떻게해야합니까?
Michael

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통합에 대해 수행했습니다. 간단하고 따라하기 쉽습니다.
cjbarth

2
2 개의 행을 반환하면 행이 예상 된 순서로 반환되는 것이 보장됩니까?
Sarsaparilla 2015 년

실행 계획이 무겁습니다
Fandango68

13

다음과 같은 것 :

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>
하비

8

나는 여기에서 모든 답을 읽었고 무슨 일이 일어나고 있는지 알아내는 데 시간이 걸렸습니다. 다음은 Moe Sisko 의 답변 및 일부 관련 연구를 기반으로합니다.

SQL 쿼리가 데이터를 반환하지 않는 경우 null 값을 가진 필드가 없으므로 ISNULL이나 COALESCE가 원하는대로 작동하지 않습니다. 하위 쿼리를 사용하여 최상위 쿼리는 null 값이있는 필드를 가져 오며 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

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

4

일치하는 레코드 없음은 반환 된 레코드가 없음을 의미합니다. 레코드가 발견되지 않으면 0의 "값"이 갈 곳이 없습니다. 원하는 작업을 수행하기 위해 미친 UNION 쿼리를 만들 수 있지만 결과 집합의 레코드 수를 확인하는 것이 훨씬 더 좋습니다.


현재 그게 제가하는 일입니다. 레코드 수가 비어 있는지 여부를 확인하십시오. 그들이 내 수표를 단축시키는 방법이라고 생각했습니다.
Matt

일부 응용 프로그램은 "단순히"확인을 허용하지 않습니다
나디아 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

나는이 접근 방식을 좋아합니다. 기본 데이터를 표현할 때, 특히 많은 데이터 / 기본값 열로 끝날 때 좀 더 깔끔하다고 느낍니다.
Mark At Ramp51

Lol 이것은 가장 좋고 깨끗한 솔루션입니다
Kyle Bridenstine

1

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]

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

1

@ 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

1
업데이트 된 답변이 작동합니다.
Andrew Cowenhoven

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.