Запрос, возвращающий строку, даже если оператор SELECT пуст, ошибочен

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

[21000][1241] (conn=80188403) Operand should contain 1 column(s)

Что не так с этим запросом?

SET @produktNummer = 01000051311;
SET @languageID = '2fbb5fe2e29a4d70aa5854ce7ce3e20b';
SELECT IFNULL(
      (SELECT product.id, product_number, property_group_translation.name AS AttributBez
       FROM product
       LEFT JOIN product_property 
         ON product.id = product_property.product_id
       LEFT JOIN property_group_option 
         ON product_property.property_group_option_id = property_group_option.id
       LEFT JOIN property_group_translation 
         ON property_group_option.property_group_id = property_group_translation.property_group_id
       WHERE product_number = @produktNummer
          AND property_group_translation.language_id = UNHEX(@languageID)
          AND (
              property_group_translation.name = '' OR
              property_group_translation.name IS NULL
              )
       )
  ,'No values');

Если я попробую без ISNULL(), я не получу никаких результатов. Если я изменю запрос таким образом, я получу обратно несколько записей.

SET @produktNummer = 01000051311;
SET @languageID = '2fbb5fe2e29a4d70aa5854ce7ce3e20b';
SELECT product.id, product_number, property_group_translation.name AS AttributBez
FROM product
LEFT JOIN product_property
ON product.id = product_property.product_id
LEFT JOIN property_group_option
ON product_property.property_group_option_id = property_group_option.id
LEFT JOIN property_group_translation
ON property_group_option.property_group_id = property_group_translation.property_group_id
WHERE product_number = @produktNummer
AND property_group_translation.language_id = UNHEX(@languageID)

Ожидаемый результат находится в части SELECT. Если значения нет, он должен вернуть «Нет значений» в виде строки. Понятия не имею, что ты имеешь в виду своим комментарием

user24710148 04.06.2024 12:46

Вы не можете этого сделать. SQL является статическим и строго типизированным. Одним из последствий является то, что один запрос всегда должен возвращать одни и те же столбцы с одинаковыми именами и одинаковыми типами данных — иногда запрос не может возвращать меньшее количество столбцов. Что вам понадобится, так это код вроде store query results in temp table, check number of rows, if 0 select string ELSE select from temp table Но это плохая идея (анти-шаблон/запах кода), поскольку подпись возвращаемых данных вашего кода изменится. Итак, это становится кси-проблемой - Почему ты хочешь это сделать? Как вы думаете, чего это дает?

MatBailie 04.06.2024 12:51

Что ж, результат этого запроса будет представлен в файле CSV другому человеку, который вообще не понимает SQL. Этому человеку проще получить строку «Нет доступных значений», чем получить пустой ответ.

user24710148 04.06.2024 12:53

Это ошибка. Им следует написать код для обработки CSV-файла с заголовком и без строк. Это не проблема SQL, это проблема разработки данных и программного обеспечения.

MatBailie 04.06.2024 12:54

Итак, это невозможно, чего я хочу?

user24710148 04.06.2024 12:55

Я уже давал псевдокод, как поступить неправильно.

MatBailie 04.06.2024 12:56

Ваш псевдокод слишком обширен. Не хотите, чтобы вам приходилось работать с представлениями или временными таблицами!

user24710148 04.06.2024 12:57

Тогда не делай ничего плохого. SQL-запросы не могут сделать неправильный результат, не преодолев препятствия. Потому что это неправильно.

MatBailie 04.06.2024 12:58

Больше ничего комментировать не буду. Вот чего я «не делаю»

user24710148 04.06.2024 12:59

Давайте продолжим обсуждение в чате.

user24710148 04.06.2024 13:30
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
10
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете получить хотя бы 1 строку с данными или значением «Нет значения».
Включите другие побочные параметры в качестве подзапроса и присоедините к ним другие данные.

(
  select @produktNummer as produktNummer, UNHEX(@languageID) as languageID
  ) request

См. пример

SET @produktNummer = 01000051311;
SET @languageID = '2fbb5fe2e29a4d70aa5854ce7ce3e20b';

SELECT produktNummer,languageID
  ,coalesce(product.id,'NoValue') id
  ,coalesce(product_number,'NoValue')product_number
  ,coalesce(property_group_translation.name,'NoValue') AS AttributBez
FROM (
  select @produktNummer as produktNummer, UNHEX(@languageID) as languageID
  ) request
left join product p on p.product_number = request.produktNummer 
LEFT JOIN product_property
   ON product.id = product_property.product_id
LEFT JOIN property_group_option
   ON product_property.property_group_option_id = property_group_option.id
LEFT JOIN property_group_translation
   ON property_group_option.property_group_id = property_group_translation.property_group_id
WHERE property_group_translation.language_id = request.languageID

Если данные не найдены, вывод

номер продукта идентификатор языка идентификатор номер продукта АтрибутБез 01000051311 2fbb5fe2e29a4d70aa5854ce7ce3e20b Неважно Неважно Неважно

Или

идентификатор номер продукта АтрибутБез Неважно Неважно Неважно

Если вы хотите только проверить, присутствуют ли данные

SET @produktNummer = 01000051311;
SET @languageID = '2fbb5fe2e29a4d70aa5854ce7ce3e20b';
SELECT 
   case when 
      (SELECT count(*)
       FROM product
       LEFT JOIN product_property 
         ON product.id = product_property.product_id
       LEFT JOIN property_group_option 
         ON product_property.property_group_option_id = property_group_option.id
       LEFT JOIN property_group_translation 
         ON property_group_option.property_group_id = property_group_translation.property_group_id
       WHERE product_number = @produktNummer
          AND property_group_translation.language_id = UNHEX(@languageID)
          AND (
              property_group_translation.name = '' OR
              property_group_translation.name IS NULL
              )
       )>0 then  'Values available'
    else 'No values'
    end result ;

Обновление 1.
Если результат запроса сохраняется в файл формата csv, все столбцы будут преобразованы в строки.

SELECT ...
INTO OUTFILE '/out-files/products.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

Это должно содержать предупреждение о том, что оно будет неявно приводить все числовые значения к строкам, даже если они не являются 'NoValue', что опять же является запахом кода/анти-шаблоном.

MatBailie 04.06.2024 14:43

Да. Я неявно предполагал, что ОП знает, в каком формате данные будут использоваться дальше. Если есть вывод в формате CSV, то преобразование в строку неизбежно.

ValNik 04.06.2024 15:02

Проблема может заключаться в том, что ФП не очень высоко оценивает сторону, получающую от него данные. Впрочем, всегда можно договориться)

ValNik 04.06.2024 15:04

Нет, CSV с 1,1,'x' сильно отличается от CSV с '1','1','x'

MatBailie 04.06.2024 16:01

Снимаю шляпу и респект, господин ВалНик. Наше решение, отличающееся высоким уровнем профессионализма, работает идеально!

user24710148 05.06.2024 20:01

Другие вопросы по теме