Выполнять подзапрос, зависящий от параметра / переменной

Мой вопрос

Я пытаюсь выполнить запрос в запросе MERGE , чтобы вывести результаты из одной таблицы в другую. Это все отлично работает, кроме одного маленького хиккупа …

Запрос, который выполняется для получения данных из таблицы, зависит от переменной, называемой @User_ID .

Если @User_ID равно NULL тогда выполните подзапрос A, иначе выполните подзапрос B.

Проблема в том, что я не знаю, как помещать IF в подзапрос … Как я могу это сделать?

То, что я пробовал …

Это то, что у меня есть до сих пор:

Обратите внимание, что это может сработать, но поскольку я запускаю SQL Server 2008 не в 2012 году (я думаю), функция IIF недоступна. Думаю, поэтому мне нужен еще один способ достижения этого.

 -- Get the relevant logins for the past 12 weeks and insert -- them into the temporary table where the week number is the same MERGE INTO #Number_Of_Logins AS NOL USING ( SELECT IIF (ISNULL(@User_ID,0), ( SELECT Year(UA.Audit_When) AS Year_Num, DatePart(wk, UA.Audit_When) AS Week_Number, Count(*) AS Num_Logins FROM User_Auditing UA WHERE Audit_Type = 'SYSLI' AND User_ID = @User_ID AND DATEDIFF(wk, Audit_When, GETDATE()) <= 11 GROUP BY Year(Audit_When), DatePart(wk, Audit_When) ), ( SELECT Year(UA.Audit_When) AS Year_Num, DatePart(wk, UA.Audit_When) AS Week_Number, Count(*) AS Num_Logins FROM User_Auditing UA JOIN User_Profiles UP ON UA.User_ID = UP.User_ID WHERE UA.Audit_Type = 'SYSLI' AND UP.Company_ID = @Company_ID AND DATEDIFF(wk, UA.Audit_When, GETDATE()) <= 11 GROUP BY Year(Audit_When), DatePart(wk, UA.Audit_When) ) ) ) AS TEST ON NOL.Week_Number = TEST.Week_Number WHEN MATCHED THEN UPDATE SET Number_Of_Logins = Num_Logins; 

Обновить

Я также пытался использовать CASE , и я получаю следующую ошибку:

Выражение небулевого типа, указанное в контексте, где ожидается условие, рядом с «THEN».

Вот ваше решение, нет необходимости контролировать поток на таком высоком уровне.

 MERGE INTO #Number_Of_Logins AS NOL USING ( SELECT Year(UA.Audit_When) AS Year_Num, DatePart(wk, UA.Audit_When) AS Week_Number, Count(*) AS Num_Logins FROM User_Auditing UA LEFT OUTER JOIN User_Profiles UP ON UA.User_ID = UP.User_ID WHERE Audit_Type = 'SYSLI' AND ( User_ID = @User_ID OR ( @User_ID IS NULL AND UP.Company_ID = @Company_ID ) ) AND DATEDIFF(wk, Audit_When, GETDATE()) <= 11 GROUP BY Year(Audit_When), DatePart(wk, Audit_When) ) AS TEST ON NOL.Week_Number = TEST.Week_Number WHEN MATCHED THEN UPDATE SET Number_Of_Logins = Num_Logins; 

В этом примере второе условие предложения where говорит: либо предоставляется @User_ID, либо идентификатор пользователя равен NULL, а соответствует идентификатору компании.

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

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

Проблема: выражения CASE и вызовы функций IIF работают со значениями, а не с результатами. По этой причине предлагаемый выше подход не будет работать в SQL Server 2012.

Одно из возможных решений: используйте UNION ALL для объединения двух возможных запросов с различными предложениями WHERE для фильтрации одного или другого набора результатов:

 -- Get the relevant logins for the past 12 weeks and insert -- them into the temporary table where the week number is the same MERGE INTO #Number_Of_Logins AS NOL USING ( SELECT Year(UA.Audit_When) AS Year_Num, DatePart(wk, UA.Audit_When) AS Week_Number, Count(*) AS Num_Logins FROM User_Auditing UA WHERE Audit_Type = 'SYSLI' AND User_ID = @User_ID AND DATEDIFF(wk, Audit_When, GETDATE()) <= 11 AND @User_ID Is Not Null GROUP BY Year(Audit_When), DatePart(wk, Audit_When) UNION ALL SELECT Year(UA.Audit_When) AS Year_Num, DatePart(wk, UA.Audit_When) AS Week_Number, Count(*) AS Num_Logins FROM User_Auditing UA JOIN User_Profiles UP ON UA.User_ID = UP.User_ID WHERE UA.Audit_Type = 'SYSLI' AND UP.Company_ID = @Company_ID AND DATEDIFF(wk, UA.Audit_When, GETDATE()) <= 11 AND @User_ID Is Null GROUP BY Year(Audit_When), DatePart(wk, UA.Audit_When) ) ) AS TEST ON NOL.Week_Number = TEST.Week_Number WHEN MATCHED THEN UPDATE SET Number_Of_Logins = Num_Logins; 

Другой вариант: имеют два полностью отдельных оператора MERGE, причем оператор IF выбирает, какой из них выполнять (более дублированный код, но может иметь кеширование запросов / производительность):

 -- Get the relevant logins for the past 12 weeks and insert -- them into the temporary table where the week number is the same IF @User_ID IS NOT NULL MERGE INTO #Number_Of_Logins AS NOL USING ( SELECT Year(UA.Audit_When) AS Year_Num ,DatePart(wk, UA.Audit_When) AS Week_Number ,Count(*) AS Num_Logins FROM User_Auditing UA WHERE Audit_Type = 'SYSLI' AND User_ID = @User_ID AND DATEDIFF(wk, Audit_When, GETDATE()) <= 11 GROUP BY Year(Audit_When) ,DatePart(wk, Audit_When) ) AS TEST ON NOL.Week_Number = TEST.Week_Number WHEN MATCHED THEN UPDATE SET Number_Of_Logins = Num_Logins; ELSE MERGE INTO #Number_Of_Logins AS NOL USING ( SELECT Year(UA.Audit_When) AS Year_Num ,DatePart(wk, UA.Audit_When) AS Week_Number ,Count(*) AS Num_Logins FROM User_Auditing UA INNER JOIN User_Profiles UP ON UA.User_ID = UP.User_ID WHERE UA.Audit_Type = 'SYSLI' AND UP.Company_ID = @Company_ID AND DATEDIFF(wk, UA.Audit_When, GETDATE()) <= 11 GROUP BY Year(Audit_When) ,DatePart(wk, UA.Audit_When) ) AS TEST ON NOL.Week_Number = TEST.Week_Number WHEN MATCHED THEN UPDATE SET Number_Of_Logins = Num_Logins; 

Скорее всего, я поеду со вторым вариантом, для (потенциальных) преимуществ производительности.

  • возврат типа бит в хранимую процедуру
  • Пользователь SQL может запускать только proc, но этот процесс может делать все
  • Получение инструкции sql, которая отображает представление, sp или функцию, MSSQL
  • Тайм-аут MS SQL на странице ASP.NET, но не в SSMS
  • Хранимая процедура SQL Server для обновления двух баз данных на серверах differrent
  • Процедура SQL Server и набор записей
  • разница в производительности между пользовательской функцией и хранимыми процедурами
  • Быстрее ли извлекать или фильтровать данные из представлений с помощью хранимой процедуры, чем получать или фильтровать данные из таблиц с помощью хранимой процедуры?
  • Вставка строк и обновление таблицы без использования SQL-курсора
  • Замена определенной подстроки на другую подстроку в строке хранимой процедуры SQL
  • Truncate Vs Delete и Table Locks SQL Server 2012
  • Interesting Posts

    Как получить последнюю дату месяца SQL Server 2008

    Поиск FREETEXT – результаты заказа в зависимости от того, насколько они близки

    Как выбрать световую версию системы баз данных

    Поля фильтра в разделе «IN» с использованием переменной

    Как получить сходство фраз в C # .NET

    Поверните бит массива внутри строки в название дня недели

    Вставка значений String, Float и DateTime в таблицу sql

    Как форматировать XML-код, когда данные поступают в одну строку

    Рекомендации по архитектуре Umbraco 4.7 для работы с узлами 200K +

    Чтение и анализ данных JSON для базы данных SQL

    Выберите XML multiple только несколько узлов с тем же именем

    В чем разница между сканированием таблиц и сканированием индексов кластеров?

    Как найти совпадающие даты в SQL Server

    Сервер MSSQL не использует индекс некластерного составного ключа (PK + FK) на InnerJoin

    Удаление ненужных индексов – влияние на планы запросов в SQL Server 2005

    Давайте будем гением компьютера.