У меня есть SQL-запрос, в котором есть немецкий и английский перевод имени. На основе пользовательских настроек и существующих данных для перевода я хочу определить вывод SQL-запроса. В моем примере CASE для выбора языка на основе пользовательских настроек работает, но вторая функция CASE не работает, потому что она не знает определения из первой функции CASE.

Я работаю над XAMPP v3.2.4/версия сервера: 10.4.11-MariaDB

Вот моя попытка:

SELECT questionaire.quest_name_de, questionaire.quest_name_en,

# CASE 1: check what language settings the user haves selected
CASE :language WHEN 'de' THEN questionaire.quest_name_de ELSE questionaire.quest_name_en END AS quest_name_translation,

# CASE 2: if the output is empty take german translation which is never empty
CASE quest_name_translation WHEN '' THEN questionaire.quest_name_de ELSE quest_name_translation END AS quest_name_final
 
FROM questionaire 
   

Мой желаемый результат выглядит следующим образом:

Настройки языка пользователя — английский, поэтому первая функция CASE в моем запросе выберет «questionaire.quest_name_en». Далее вторая функция CASE проверит, не пусты ли данные для 'quest_name_translation'. Если он пуст, выберите «questionaire.quest_name_de». Моя проблема в том, что второй СЛУЧАЙ не знает «quest_name_translation» из первого СЛУЧАЯ. этот способ невозможен?

0
Mischa Mustermann 26 Янв 2022 в 15:47
3
Позвольте мне предложить вам удалить код PHP из вопроса, это сделает ваш вопрос более ясным. Вместо этого лучше добавить имя сервера базы данных и версию
 – 
Your Common Sense
26 Янв 2022 в 15:49
Извините, но какой PHP-код вы видите? Я только что добавил SQL-запрос, и мой вопрос напрямую связан с этой функцией CASE в SQL-запросе. Почему имя базы данных имеет значение и какой номер версии вы хотите знать? На самом деле не уверен, что ты хочешь от меня. Прошу прощения, а вы не перепутали тут какие-то вопросы?
 – 
Mischa Mustermann
26 Янв 2022 в 15:56
1
$statement = $pdo->prepare - это, например, PHP. SQL начинается с SELECT. Диалекты SQL различаются, и то, что работает в одной СУБД, может не работать в другой. Поэтому всегда помечайте ваши SQL-запросы тегом используемой СУБД. И в идеале вы также сообщите нам версию, потому что это тоже может иметь значение.
 – 
Thorsten Kettner
26 Янв 2022 в 16:04
Я надеюсь, что теперь все так, как вы ожидали ^^
 – 
Mischa Mustermann
26 Янв 2022 в 16:14

1 ответ

Лучший ответ

Используйте AND для объединения условий. Только если английский язык запрошен и английский доступен, вы покажете английский текст, в противном случае немецкий:

SELECT
  questionaire.quest_name_de,
  questionaire.quest_name_en,
  CASE WHEN :language = 'en' AND quest_name_en <> '' AND quest_name_en IS NOT NULL
    THEN quest_name_en
    ELSE quest_name_de
  END AS quest_name_final
FROM questionaire;
1
Thorsten Kettner 26 Янв 2022 в 16:00
COALESCE() было бы проще.
 – 
wildplasser
26 Янв 2022 в 16:03
Кеттнер, спасибо за это идеальное рабочее решение!
 – 
Mischa Mustermann
26 Янв 2022 в 16:08
Нужно ли мне также «И quest_name_en IS NOT NULL», если строка таблицы определяется как текст, а не как INT? Я думаю, вы добавили это, чтобы избежать «0» в результате, верно?
 – 
Mischa Mustermann
26 Янв 2022 в 16:18
Если столбец определен как NOT NULL, то NULL невозможен, но в противном случае текст может быть пустым двумя способами: либо как NULL, либо как пустая строка ''. Но вы все равно правы, quest_name_en <> '' уже исключает NULL. Так что нет, quest_name_en IS NOT NULL не нужен.
 – 
Thorsten Kettner
26 Янв 2022 в 16:30
@wildplasser: я в этом сомневаюсь. Как будет выглядеть это выражение COALESCE, элегантно проверяющее запрошенный язык и учитывающее как null, так и пустую строку?
 – 
Thorsten Kettner
26 Янв 2022 в 16:32