Использование ISNULL в SQL LEFT JOIN для проверки, равен ли результат null, и если это так, используйте другое значение для объединения

#sql #sql-server

#sql #sql-server

Вопрос:

У меня есть SQL select с предложением where, где я хочу проверить, равен ли результат null, и если это null, я хочу использовать другое значение в предложении where, но я получаю результаты 0 строк, хотя я знаю, что в результате я должен получить строку.

Вот мой (обновленный) SQL-код:

 DECLARE @LanguageCode NVARCHAR(3);
SET @LanguageCode = 'FR'
SELECT 
wi.WorkItemId,
ds.DisplayString AS Team
FROM dbo.WorkItem AS wi 
LEFT JOIN dbo.DisplayString AS ds ON ds.ElementID = wi.TierId AND ds.LocaleID = ISNULL(@LanguageCode, 'ENU')
  

Приведенный выше код возвращает данные для «@LanguageCode», когда есть данные для возврата, но он не переключается на использование ‘ENU’, когда данных нет. Вот в чем проблема!

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

Чтобы уточнить, чего я хочу достичь, если c.LocaleID = @LanguageCode возвращает нулевые строки, я хочу использовать жестко заданное значение, как в c.LocaleID = ENU .

Если я не использую функцию ISNULL и использую только ‘ENU’, она возвращает ожидаемый результат.

Я был бы признателен за любую помощь. Спасибо.

Комментарии:

1. Присвоение имени таблице column1 вызывает некоторый когнитивный диссонанс.

2. У вас есть значения языкового кода объемом 2 ГБ? Если нет, я предлагаю вам указать соответствующий максимальный размер вместо nvarchar(MAX) .

3. Это не настоящее имя столбца, но я изменил его по соображениям цензуры.

4. это не значения размером 2 ГБ, но этот фрагмент SQL — всего лишь часть большего запроса, и я просто написал max для упрощения.

5. c.LocaleID = ISNULL(@LanguageCode, ‘ENU’) может быть c.LocaleID = (@LanguageCode равно нулю или @LanguageCode = ‘ENU’)

Ответ №1:

Если я правильно понимаю, вам нужна одна строка, либо с указанным кодом языка, либо 'ENU' . Если это так, используйте фильтрацию и ORDER BY :

 SELECT TOP (1) c.*
FROM dbo.column1 c 
WHERE c.rowID = '1234-1234-1234' AND 
      c.LocaleID IN (@LanguageCode, 'ENU')
ORDER BY (CASE WHEN c.LocaleID = @LanguageCode THEN 1 ELSE 2 END)
  

Комментарии:

1. Спасибо за ваш быстрый ответ. Да, это то, что я хочу, но я хочу вернуть только 1 строку, если есть данные для обоих языковых кодов. Я попробовал ваш ответ, но затем я получаю обе строки, возвращаемые при наличии данных для обоих языковых кодов. Есть какие-нибудь подсказки?

2. @arkenfar . . . Этот запрос не может вернуть две строки из-за SELECT TOP (1) .

3. Но я хочу вернуть все результаты, но когда LocaleID равен NULL, он должен возвращать результат для LocaleID = ‘ENU’ .. Смотрите Мой обновленный код выше, который намного больше похож на весь запрос, за исключением того, что есть много ЛЕВЫХ СОЕДИНЕНИЙ, где мне нужна такая же проверка по LocaleID. Спасибо.

Ответ №2:

Я думаю, вы ищете это

 select coalesce((SELECT rowID FROM dbo.column1 where c.rowID = '1234-1234-1234' and LocaleID = @LanguageCode),
                (SELECT rowID FROM dbo.column1 where c.rowID = '1234-1234-1234' and LocaleID = 'ENU')); 
  

Комментарии:

1. Я попробовал это сейчас, и оно возвращает ошибку, в которой говорится «В списке выбора может быть указано только одно выражение, когда подзапрос не вводится с помощью EXISTS»

2. Извините, не удалось использовать подстановочный знак. Я изменил selects, чтобы вернуть rowID .

Ответ №3:

Я полагаю, вы ищете что-то вроде этого:

 SELECT *
FROM table_name c
WHERE c.LocaleID  = 
      case when (select count(*) 
                 from table_name tn
                 where tn.LocaleID = @LanguageCode) = 0 then
          'ENU'
      else
           @LanguageCode
      end;
  

Вот демонстрация.

Вот новая демонстрация: https://dbfiddle.uk/?rdbms=sqlserver_2019amp;fiddle=624100ee44f89decc4c6383e92d0a016

В новой демонстрации я добавил еще немного кода, чтобы показать, как использовать его в left join как часть условия объединения, а также я добавил код, чтобы показать, как использовать его в предложении where при объединении двух таблиц, и я полагаю, что он относится к предложению where…

Комментарии:

1. Сейчас я проверяю другие ответы и не понимаю, почему ответ Гордона у вас не работает?

2. вероятно, мне следовало сразу упомянуть об этом, причина, по которой это не работает, заключается в том, что мой запрос является всего лишь частью более крупного запроса, и реальный случай для меня — использовать функцию ISNULL () в левом соединении для нескольких столбцов. И при использовании «IN» я получу дублированный результат на разных языках (это запрос, возвращающий результат на основе языка, и если возвращаемые данные равны 0, он должен возвращать ENU, поскольку это всегда данные для ENU). Я просто подумал, что это упростит ситуацию, если я просто напишу пример того, чего я пытаюсь достичь.

3. Итак , работает ли это мое решение ? Не могли бы вы привести нам пример данных и усложнить его, потому что без примеров …. больше ничего нельзя сделать…

4. Привет @arkenfar, ты не ответил на мой вопрос: почему мой код тебе не подходит?

5. Потому что я не вижу, как я могу использовать это в моем левом соединении?