простой вопрос, но понятия не имею, как это исправить. Следующий запрос должен вернуть «Нет значений», если часть 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)
Вы не можете этого сделать. SQL является статическим и строго типизированным. Одним из последствий является то, что один запрос всегда должен возвращать одни и те же столбцы с одинаковыми именами и одинаковыми типами данных — иногда запрос не может возвращать меньшее количество столбцов. Что вам понадобится, так это код вроде store query results in temp table, check number of rows, if 0 select string ELSE select from temp table
Но это плохая идея (анти-шаблон/запах кода), поскольку подпись возвращаемых данных вашего кода изменится. Итак, это становится кси-проблемой - Почему ты хочешь это сделать? Как вы думаете, чего это дает?
Что ж, результат этого запроса будет представлен в файле CSV другому человеку, который вообще не понимает SQL. Этому человеку проще получить строку «Нет доступных значений», чем получить пустой ответ.
Это ошибка. Им следует написать код для обработки CSV-файла с заголовком и без строк. Это не проблема SQL, это проблема разработки данных и программного обеспечения.
Итак, это невозможно, чего я хочу?
Я уже давал псевдокод, как поступить неправильно.
Ваш псевдокод слишком обширен. Не хотите, чтобы вам приходилось работать с представлениями или временными таблицами!
Тогда не делай ничего плохого. SQL-запросы не могут сделать неправильный результат, не преодолев препятствия. Потому что это неправильно.
Больше ничего комментировать не буду. Вот чего я «не делаю»
Давайте продолжим обсуждение в чате.
Вы можете получить хотя бы 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
Если данные не найдены, вывод
Или
Если вы хотите только проверить, присутствуют ли данные
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'
, что опять же является запахом кода/анти-шаблоном.
Да. Я неявно предполагал, что ОП знает, в каком формате данные будут использоваться дальше. Если есть вывод в формате CSV, то преобразование в строку неизбежно.
Проблема может заключаться в том, что ФП не очень высоко оценивает сторону, получающую от него данные. Впрочем, всегда можно договориться)
Нет, CSV с 1,1,'x'
сильно отличается от CSV с '1','1','x'
Снимаю шляпу и респект, господин ВалНик. Наше решение, отличающееся высоким уровнем профессионализма, работает идеально!
Ожидаемый результат находится в части SELECT. Если значения нет, он должен вернуть «Нет значений» в виде строки. Понятия не имею, что ты имеешь в виду своим комментарием