MySQL возвращает пустое поле: CONCAT (nonEmpty1, empty2, nonEmpty3) = NULL
У меня есть код PHP 5, доступ к таблице MyISAM на сервере MySQL 5. Запрос выглядит следующим образом:
SELECT CONCAT(fName1,' ',mName2,' ',lName3) AS userName
FROM users
WHERE level > 10
Когда нет имени mName, Я ожидаю вывод, например, "fname lname", но вместо этого я получаю "" (пустую строку) (количество возвращаемых строк верное). Где я ошибаюсь?
PHP-код:
<?php
$result = mysql_query($the_above_query);
while ($result_row = mysql_fetch_assoc($result)) {
// do stuff with the name
// except I'm getting empty strings in $result_row['userName']
}
Соответствующая часть структуры таблицы:
CREATE TABLE users {
/* -snip- */
`fName1` varchar(50) default NULL,
`mName2` varchar(50) default NULL,
`lName3` varchar(50) default NULL,
`level` int(11) default 0,
/* -snip- */
} ENGINE=MyISAM DEFAULT CHARSET=utf8;
(также, этот способ (конкатенация столбцов в MySQL) хорошая идея, или мне нужно получить столбцы для PHP и присоединиться к ним там?)
Оказывается, что я возвращаю NULL; PHP обрабатывает возвращенную NULL и пустую строку ("") аналогично, вам нужно будет сравнить с ===, чтобы увидеть разницу.
Ответы
Ответ 1
Из google: http://bugs.mysql.com/bug.php?id=480
[23 мая 2003 4:32] Александр Керемидарский
Спасибо, что нашли время написать нам, но это не
Жук. Пожалуйста, дважды проверьте документацию на
http://www.mysql.com/documentation/ и инструкции по
как сообщить об ошибке в http://bugs.mysql.com/how-to-report.php
Это документированное поведение функции CONCAT().
В главе "Руководство" 6.3.2 "Строковые функции"
CONCAT (str1, str2,...)
Возвращает строку, которая возникает при объединении аргументов. Возвращает NULL, если таковой имеется
аргумент NULL
Вместо этого используйте CONCAT_WS() или оберните пареметры NULLable функцией IFNULL().
Документация и использование для CONCAT_WS: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_concat-ws
Ответ 2
Из документов MYSQL
CONCAT() возвращает NULL, если любой аргумент имеет значение NULL.
вы хотите использовать CONCAT_WS()
CONCAT_WS(separator,str1,str2,...)
Но лучше всего просто вернуть его и использовать php-причину, если вам нужен другой формат или только одно из этих полей позже, вам придется сделать другой вызов db
Ответ 3
В MySQL, связывающем любую строку с значением NULL, получается NULL.
Вы должны проверить NULL перед конкатенацией, используя IFNULL:
SELECT CONCAT(IFNULL(fName1,''),' ',IFNULL(mName2,''),' ',IFNULL(lName3,'')) AS userName
FROM users
WHERE level > 10
Ответ 4
Это было решение, с которым я столкнулся, включая ответ Keeper и Ersatz. Система не позволила бы мне проголосовать за вас, ребята, хотя: (
CONCAT_WS(IFNULL(ts_usr_nameDetails.first_name,''),' ',IFNULL(ts_usr_lib_connectionNameDetails.first_name,'')) AS composerName
Это позволило сделать некоторые удивительные результаты
Ответ 5
Это ответ на основе вышеизложенного решения @chocojosh и еще один вопрос: MySQL/SQL: обновление с коррелированным подзапросом из самой обновленной таблицы
У меня была аналогичная проблема, но я пытался конкатенировать группу group_concats, а некоторые из них были NULL, что привело к тому, что вся строка была NULL. Цель состояла в том, чтобы поместить данные из других таблиц в одно поле в основной таблице, чтобы обеспечить полнотекстовый поиск.
Вот SQL, который сработал. Обратите внимание на первый параметр для concat_ws, который я сделал ', это позволило пробелы между значениями для поля полного текста.
Надеюсь, это поможет кому-то.
update
products target
INNER JOIN
(
select p.id,
CONCAT_WS(
' ',
(select GROUP_CONCAT(field SEPARATOR ' ') from table1 where productId = p.id),
p.title,' ',
(select GROUP_CONCAT(field, ' ', descriptions SEPARATOR ' ') from table2 where productId = p.id),
(select GROUP_CONCAT(field SEPARATOR ' ') from table3 where productId = p.id),
(select GROUP_CONCAT(field, ' ', catno SEPARATOR ' ') from table4 where productId = p.id),
(select GROUP_CONCAT(field SEPARATOR ' ') from table5 where productId = p.id),
(select GROUP_CONCAT(field SEPARATOR ' ') from table6 where productId = p.id),
(select GROUP_CONCAT(field SEPARATOR ' ') from table7 where productId = p.id)
) as ft
from products p
) as source
on target.id = source.id
set target.fulltextsearch = source.ft
Ответ 6
вы также можете использовать функцию COALESCE()
, чтобы вернуть первое ненулевое значение. Например:
SELECT CONCAT(fName1,COALESCE(CONCAT(' ',mName2,' '),' '),lName3) AS userName
FROM users
WHERE level > 10
Это также помещало бы только одно пространство, если бы не было промежуточного имени и пробела до и после, если было среднее имя.
Ссылка на эту функцию можно найти по адресу: http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce