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 и пустую строку ("") аналогично, вам нужно будет сравнить с===, чтобы увидеть разницу.

6 ответов


из google:http://bugs.mysql.com/bug.php?id=480

[23 Мая 2003 4:32] Александр Keremidarski

Спасибо, что нашли время написать нам, но это не жук. Пожалуйста, проверьте в документации по http://www.mysql.com/documentation/ и инструкции на как сообщить об ошибке вhttp://bugs.mysql.com/how-to-report.php

Это doccumented поведение функции concat() функция.

из руководства глава 6.3.2 строковые функции

функция concat(str1 выглядит следующим образом,стр2,...) Возвращает строку, которая является результатом объединения аргументов. Возвращает NULL, если таковые имеются аргумент равен NULL

вместо этого используйте CONCAT_WS() или оберните нулевые пареметры с функцией IFNULL ().

документация и использование для CONCAT_WS: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_concat-ws


из MYSQL docs

CONCAT () возвращает NULL, если какой-либо аргумент имеет значение NULL.

вы хотите использовать CONCAT_WS()

CONCAT_WS(separator,str1,str2,...)

но лучше всего просто вернуть его и использовать php, потому что, если вам нужен другой формат или только одно из этих полей позже, вам придется сделать еще один вызов db


в MySQL обьединении любую строку на null значение в null. Вы должны проверить значение NULL перед конкатенацией, используя IFNULL:

SELECT CONCAT(IFNULL(fName1,''),' ',IFNULL(mName2,''),' ',IFNULL(lName3,'')) AS userName 
FROM users 
WHERE level > 10

Это было решение, которое я придумал, которое включало Keeper и эрзац-ответ. Система не позволила бы мне проголосовать за вас, ребята, хотя: (

CONCAT_WS(IFNULL(ts_usr_nameDetails.first_name,''),' ',IFNULL(ts_usr_lib_connectionNameDetails.first_name,'')) AS composerName

Это позволило для некоторых удивительных результатов


это ответ, основанный на решении выше @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

вы также могли 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