MySQL возвращает пустое поле: CONCAT (nonEmpty1, empty2, nonEmpty3) = NULL - PullRequest
13 голосов
/ 11 июня 2009

У меня есть код 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 ]

25 голосов
/ 11 июня 2009

От 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 paremeters функцией IFNULL ().

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

16 голосов
/ 11 июня 2009

Из документов MYSQL

CONCAT () возвращает NULL, если есть аргумент НЕДЕЙСТВИТЕЛЕН.

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

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

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

11 голосов
/ 11 июня 2009

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

SELECT CONCAT(IFNULL(fName1,''),' ',IFNULL(mName2,''),' ',IFNULL(lName3,'')) AS userName 
FROM users 
WHERE level > 10
3 голосов
/ 06 апреля 2011

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

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

Это дало удивительные результаты

1 голос
/ 12 февраля 2013

Вы также можете использовать функцию 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

1 голос
/ 13 октября 2012

Это ответ, основанный на приведенном выше решении @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
...