2016-08-25 2 views
0

У меня есть простой SELECT ...SQL: Как вернуть все NULL, если запись не найдена?

SELECT TETmeetingID, 
     DateID, 
     WeekNo, 
     TETID, 
     TradeStaffID, 
     EngStaffID, 
     MathsStaffID, 
     IoTStaffID, 
     Others, 
     TradeStaffPresent, 
     EngStaffPresent, 
     MathsStaffPresent, 
     IoTStaffPresent, 
     CurricTrade, 
     CurricEnglish, 
     CurricMaths, 
     CurricIoT, 
     CurricAlign, 
     Notes, 
     WeeksToGo, 
     TotalWeeks, 
     CreatedDate, 
     CreatedBy, 
     Complete, 
     CompletedDate, 
     CompletedBy 
FROM tblTETMeeting 
WHERE TETmeetingID = @SomeParameter 

Работы, конечно, когда пункт WHERE возвращает true.

Но если это не так, я хочу, по крайней мере, увидеть одну запись с NULL в каждом столбце.

Как я могу это сделать, пожалуйста? И я выбрал приведенный выше пример, чтобы показать возможное количество столбцов, которые я мог бы использовать, поэтому, если есть более общий запрос, который может «определять» столбцы и не иметь жесткого кода в ответ, это было бы предпочтительнее.

Благодаря

UPDATE

Я попытался WITH TIES, но это также не возвращает одну запись. Возможно, я делал это неправильно. Я также попробовал трюк UNION NULL, NULL, и т. Д., Но это грязно, когда количество столбцов может быть неопределенным «n». Единственный способ сделать это правильно, но я все еще вынужден предоставить правильное количество NULL с запросом типа CTE.

WITH CTE ( SELECT TETmeetingID, 
      DateID, 
      WeekNo, 
      TETID, 
      TradeStaffID, 
      EngStaffID, 
      MathsStaffID, 
      IoTStaffID, 
      Others, 
      TradeStaffPresent, 
      EngStaffPresent, 
      MathsStaffPresent, 
      IoTStaffPresent, 
      CurricTrade, 
      CurricEnglish, 
      CurricMaths, 
      CurricIoT, 
      CurricAlign, 
      Notes, 
      WeeksToGo, 
      TotalWeeks, 
      CreatedDate, 
      CreatedBy, 
      Complete, 
      CompletedDate, 
      CompletedBy 
    FROM tblTETMeeting 
    WHERE TETmeetingID = @SomeParameter) AS tbl1 

select * from CTE WHERE cte.TETmeetingID IS NOT NULL UNION SELECT NULL,NULL,NULL, etc 
+1

http: // stackoverflow.com/questions/8098795/return-a-value-if-no-record-is-found – whizzle

+0

Такое поведение лучше всего обрабатывать на уровне приложения, а не в запросе. – sstan

+0

Помимо того факта, что я не думаю, что это должно быть сделано в SQL, самый простой способ сделать это (IMO) - с инструкцией IF/ELSE. например 'if exists (выберите 1 из tblTETMeeting WHERE TETmeetingID = @SomeParameter) THEN myQuery ELSE SELECT NULL, NULL ...'. В качестве альтернативы, ответы на связь whizzle работают, если ожидается только одна строка. – ZLK

ответ

2

Это делает то, что вы хотите:

SELECT C.* 
FROM 
(SELECT 1 As DummyColumn) As DummyTable 
LEFT OUTER JOIN 
tblTETMeeting C 
ON TETmeetingID = @SomeParameter 
+0

Отлично! Да, это сработало. Но как?! Как делает один SELECT 1? – Fandango68

+1

Таблица под названием «DummyTable» - это всего лишь одна запись с одним столбцом. Итак, теперь у вас есть одна запись, независимо от того, что. Затем вы можете присоединить его к своей «реальной» записи, которая может или не может существовать. Опционально я имею в виду использование «OUTER JOIN». 1 ничего не значит. Вы можете использовать '(SELECT 'Mastodon' As MyFavouriteBand) как MyFavouriteStuff', и он все равно будет работать. Но предупреждение: «SELECT *» - это плохая практика по многим причинам - не привыкнуть к ее использованию. –

1

Это должно быть сделано.

Идея состоит в том, чтобы добавить столбец флага и дополнительную строку с NULL во всех столбцах, кроме столбца флага. В этом примере ConditionTrue - это столбец флага. 1 как true, а 0 - false. Это означает, что если предикат в WHERE равен true, результатом будут все строки, возвращаемые с ConditionTrue из 1 плюс строка с нулевым значением с ConditioinTrue из 0. С другой стороны, если ничего не было возвращено, это будет просто строка null с ConditionTrue из 0. Помещая результат в таблицу temp, вы можете отфильтровать нежелательные строки и столбцы.

Если предикат является истинным, тогда всегда будет 2 или более строк. Таким образом, вы можете проверить @@ ROWCOUNT в ваших интересах. 1 означает отсутствие удара, больший означает попадание.

И наконец, я не хочу набирать все 26 столбцов, поэтому я опустил столбец ConditionTrue и использовал SELECT * в качестве ярлыка. Если вы не возражаете против столбца флага, оставьте его, или вы можете переместить оператор ALTER перед блоком IF и отфильтровать по-другому, например TETmeetingID IS NOT NULL.

IF OBJECT_ID('Tempdb..#tblTETMeeting','U') IS NOT NULL 
    DROP TABLE Tempdb..#tblTETMeeting; 

DECLARE @COUNTS INT; 

SELECT TETmeetingID, 
     DateID, 
     WeekNo, 
     TETID, 
     TradeStaffID, 
     EngStaffID, 
     MathsStaffID, 
     IoTStaffID, 
     Others, 
     TradeStaffPresent, 
     EngStaffPresent, 
     MathsStaffPresent, 
     IoTStaffPresent, 
     CurricTrade, 
     CurricEnglish, 
     CurricMaths, 
     CurricIoT, 
     CurricAlign, 
     Notes, 
     WeeksToGo, 
     TotalWeeks, 
     CreatedDate, 
     CreatedBy, 
     Complete, 
     CompletedDate, 
     CompletedBy, 
     1 AS ConditionTrue 
INTO #tblTETMeeting 
FROM tblTETMeeting 
WHERE TETmeetingID = @SomeParameter 
UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, NULL,NULL, NULL,NULL, NULL, NULL, NULL, NULL, NULL,NULL, NULL,NULL, NULL, NULL, NULL, NULL, NULL,NULL, NULL,NULL,NULL, 0; 

SET @COUNTS = @@ROWCOUNT; 

IF @COUNTS > 1 

    SELECT * FROM #tblTETMeeting WHERE ConditionTrue = 1; 
ELSE 
    BEGIN 
     ALTER TABLE #tblTETMeeting 
      DROP COLUMN ConditionTrue; 
     SELECT * FROM #tblTETMeeting; 
    END; 
+0

Спасибо за этот длинный ответ, но я предпочел бы другой ответ, где все это в одной команде SQL. – Fandango68

0

Помните UNION является аналогом логического OR:

SELECT TETmeetingID 
    FROM tblTETMeeting 
WHERE TETmeetingID = @SomeParameter 
UNION 
SELECT NULL AS TETmeetingID -- don't make me write them all out! 
    FROM tblTETMeeting 
WHERE TETmeetingID <> @SomeParameter 

Говоря о логике, помните, в SQL условие поиска (WHERE положение) может оценивать true, false и unknown из-за запутанности SQL (и incon строго применяемая) трехзначная логика. Поэтому, если TETmeetingID или @SomeParameter может быть пустым, тогда вам может понадобиться добавить код для его обработки.

Смежные вопросы