2014-08-27 7 views
0

Я создаю запрос, который обеспечивает выполнение некоторых ограничений. Вот пол-рабочего вариант прямо сейчас:Возвращает результат запроса, даже если предложение WHERE не встречается

SELECT CASE 
      WHEN TaskId IS NULL THEN 0 
      ELSE 1 
     END AS TaskExists, 
     CASE 
      WHEN IsDownTask = 0 AND TaskStatus = 63 THEN 1 
      WHEN IsDownTask = 1 THEN 1 
      ELSE 0 
     END AS PressReady, 
     CASE 
      WHEN IsDownTask = 1 AND MachineId <> 2710 THEN 1 
      ELSE 0 
     END AS DownTaskAssignedToDifferentMachine 
FROM Task T 
WHERE TaskId = 555555 

Это прекрасно работает, когда TaskId существует в Task таблицы, но мне также нужно возвращать значения, если это задачи не существует (отсюда TaskExists поля).

Для запроса на несуществующий задачи, я бы ожидать, чтобы вернуться

  • TaskExists 0
  • PressReady 0
  • DownTaskAssignedToDisfferentMachine 0

Как я могу изменить мой запрос вернуть это, даже если нет TaskId?

+0

Когда 'taskId' не существует в этой таблице, где еще она существует? –

+0

Это можно сделать, используя, возможно, довольно уродливый оператор SQL. Если бы я был вами, я бы просто оставил такой SQL и реализовал [Null Object] (http://en.wikipedia.org/wiki/Null_Object_pattern) на стороне C#, в которой перечислены атрибуты. Я бы использовал нулевой объект, если SQL не возвращает результат – GolfWolf

+0

Является ли TaskId уникальным в этой таблице? – Bulat

ответ

14

Если вы хотите, чтобы вернуть эти значения просто обернуть каждый столбец с SUM и ISNULL:

SELECT ISNULL(SUM(CASE 
     WHEN TaskId IS NULL THEN 0 
     ELSE 1 
    END), 0) AS TaskExists, 
    ISNULL(SUM(CASE 
     WHEN IsDownTask = 0 AND TaskStatus = 63 THEN 1 
     WHEN IsDownTask = 1 THEN 1 
     ELSE 0 
    END), 0) AS PressReady, 
    ISNULL(SUM(CASE 
     WHEN IsDownTask = 1 AND MachineId <> 2710 THEN 1 
     ELSE 0 
    END), 0) AS DownTaskAssignedToDifferentMachine  
+1

Я бы просто использовал 'count (TaskId)' для 'TaskExists'. –

+0

Граф тоже будет работать, и мы также устраним выражение case. Хорошая идея. –

+0

Да, это работает так, как я хочу. Я предложил редактировать, чтобы добавить 'ISNULL' чеки в последние два поля. В противном случае они возвращают 'NULL', и я хочу избежать необходимости возвращать nullable ints из БД. – Killnine

-1

Пожалуйста, попробуйте следующий код. Я не тестировал.

SELECT CASE 
       WHEN TaskId IS NULL THEN 0 
       ELSE 1 
      END AS TaskExists, 
      CASE 
       WHEN IsDownTask = 0 AND TaskStatus = 63 THEN 1 
       WHEN IsDownTask = 1 THEN 1 
       ELSE 0 
      END AS PressReady, 
      CASE 
       WHEN IsDownTask = 1 AND MachineId <> 2710 THEN 1 
       ELSE 0 
      END AS DownTaskAssignedToDifferentMachine 
    FROM Task T 
    WHERE 1= case when TaskId = 555555 then 1 
    else 0 end 
+0

Рекомендуем отредактировать это: ваш ELSE был «o» вместо нуля. Хорошо, что вы отметили его как непроверенный, но в будущем, возможно, стоит потратить дополнительное время, чтобы проверить свои ответы прежде, чем опубликовать их. Более качественный ответ, даже на несколько минут позже, намного лучше опубликовать что-либо с помощью вопрос. – AHiggins

1

Вы можете попробовать что-то вроде этого:

DECLARE @task INT 
SET @task = 555555 

SELECT CASE 
      WHEN TaskId IS NULL THEN 0 
      ELSE 1 
     END AS TaskExists, 
     CASE 
      WHEN IsDownTask = 0 AND TaskStatus = 63 THEN 1 
      WHEN IsDownTask = 1 THEN 1 
      ELSE 0 
     END AS PressReady, 
     CASE 
      WHEN IsDownTask = 1 AND MachineId <> 2710 THEN 1 
      ELSE 0 
     END AS DownTaskAssignedToDifferentMachine 
FROM Task T 
WHERE TaskId = @task 
UNION ALL 
SELECT 0 TaskExists, 0 PressReady, 0 DownTaskAssignedToDifferentMachine 
WHERE NOT EXISTS (SELECT * FROM Task WHERE TaskId = @task) 
1

Если он должен быть в запросе, а не в коде, а затем просто обмануть и лавировать строку по умолчанию на конце вашего запроса , Гарантия, что сортирует по умолчанию после любого возможного результата, истинный и предел к вашей первой строке:

SELECT TOP 1 * FROM (
    SELECT 1 AS TaskExists, CASE ... END AS PressReady, CASE ... AS WowYouHaveALongFieldNameHere 
    FROM Task 
    WHERE TaskID = 55555 

    UNION 

    -- default if no matching row 
    SELECT 0,    0,       0 
) ORDER BY TaskExists DESC; 

Вы можете найти это более читаемым, чем альтернативные варианты с участием агрегатных функций или вынуждающих объединение и COALESCE/ISNULLing и т.д.