Повернути значення, якщо в Microsoft tSQL не знайдено рядків


95

Використовуючи версію SQL для Microsoft , ось мій простий запит. Якщо я запитую запис, який не існує, я нічого не поверну. Я вважаю за краще, щоб у цьому сценарії було повернуто значення 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

Відповіді:


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 else QTIB_REQ_ закінчується з qb_requisitions_all де QTIB_REQ_ IN ($ Req_disabled_WA) і CLIENT___BENCH___NON_BILLABLE NOT IN ('Non Billable', 'Non-Billable', 'Non-Bill', 'Non-Bill', 'Non-Bill', 'Non-Bill', 'Non-Bill', 'Non-Bill', 'Non-Bill', 'Non-Billable', 'Non-Bill', 'Non-Billable', 'Non-Bill', 'Non-Billable', 'Non-Billable', 'Non-Billable' ' SC Clearing Strategic Hires ',' Bench / US project ') and DATEDIFF (CURDATE (), TARGET_FILL_DATE) <60 and DATEDIFF (CURDATE (), TARGET_FILL_DATE)> 0
Praneet Bahadur

122

Це схоже на Адам Робінсон, але використовує 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
Дякуємо, що додали цей! Це саме те, що мені потрібно, оскільки я міг би просто ВИБРАТИ ІСНУЛЬ ((ВИБРАТИ Ідентифікатор ... замість 1, щоб отримати дані, які я шукав!
Джессі Сміт,

3
Я знаю дуже пізно, але ви можете замінити ISNULL на COALESCE, щоб отримати той самий результат.
BlueChippy

2
У мене з’явилася звичка використовувати COALESCE, а не ISNULL, оскільки з пам’яті (звички важко вмирають) ISNULL недоступний у SQL Lite або як би там не було, що працює на старих пристроях Windows Mobile. COALESCE працює як на Lite, Express, так і на повномасштабному SQL.
Оголошення

1
Це працює краще, якщо ви хочете отримати значення змінної, а не 0 або 1. Запит Адама вимагає групування або чогось подібного.
Драк

@MoeSisko Мені подобається, як він повертає 0, якщо він нульовий, але замість повернення 1, як я можу отримати його, щоб повернути значення з таблиці?
Майкл

21

Це може бути мертвий кінь, ще один спосіб повернути 1 рядок, коли не існує рядків, - це об’єднати ще один запит та відобразити результати, коли в таблиці немає.

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

І це важко для плану страти
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 1і select 2я додавas <colName>
Харві

8

Я прочитав тут усі відповіді, і пішов час, щоб зрозуміти, що відбувається. Далі ґрунтується на відповіді Мо Сіско та деяких супутніх досліджень

Якщо ваш запит SQL не повертає жодних даних, немає поля з нульовим значенням, тому ні 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

Вам потрібно лише замінити 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, щоб робити те, що хочете, але набагато, набагато краще, просто перевіряючи кількість записів у наборі результатів.


В даний час я цим і займаюся. Перевірте, яка кількість записів порожня чи ні. Прикинув, вони, можливо, були способом швидкого доступу до мого чека.
Matt

Деякі додатки не дозволяють "просто" перевірити
Надя Соловйова

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

Лол, це найкраще і найчистіше рішення
Кайл Бріденстін,

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]


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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.