2009-06-11 19 views
13

Tengo el código PHP 5 accediendo a una tabla MyISAM en el servidor MySQL 5. La consulta es el siguiente:MySQL devuelve un campo vacío: CONCAT (nonEmpty1, empty2, nonEmpty3) = NULL

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

Cuando no hay MNAME rellenado, estoy esperando una salida como "fnombre lname", pero me estoy haciendo "" (cadena vacía) en lugar (el número de filas devueltas es correcto). ¿Dónde estoy cometiendo un error?

código 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'] 
} 

parte relevante de la estructura de tabla:

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; 

(también, es de esta manera (concatenación columna en MySQL) es una buena idea, o debería ir a buscar las columnas de PHP y unirse a ellos allí)


Resulta que me estaba volviendo un NULL; PHP trata un NULL devuelto y una cadena vacía ("") de manera similar, tendría que comparar con === para ver la diferencia.

Respuesta

25

de Google: http://bugs.mysql.com/bug.php?id=480

[23 de mayo de de 2003 04:32] Alexander Keremidarski

Gracias por tomarse el tiempo para escribir a nosotros, pero esto no es un error . Comprueba por favor la documentación disponible en http://www.mysql.com/documentation/ y las instrucciones sobre cómo informar de un fallo en http://bugs.mysql.com/how-to-report.php

Este comportamiento se doccumented de la función CONCAT().

De Manual capítulo 6.3.2 Funciones de cadena

CONCAT (str1, str2, ...) devuelve la cadena resultado de concatenar los argumentos. Devuelve NULL si cualquier argumento es NULL

Utilice CONCAT_WS() en su lugar o ajuste los parámetros NULLable con la función IFNULL().

documentación y el uso de CONCAT_WS: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_concat-ws

+0

agradable encontrar en 'CONCAT_WS()' – redolent

11

En MySQL concatenación de cualquier cadena en un valor nulo resultado en NULL. Hay que comprobar NULL antes de concatenar usando IFNULL:

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

a partir de documentos MYSQL

CONCAT() devuelve NULL si cualquier argumento es NULL .

que desea utilizar CONCAT_WS()

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

Pero lo mejor es simplemente tirar de ella y utilizar php causa si necesita un formato diferente o simplemente uno de esos campos temprano tendrás para hacer otra llamada a base de datos

+0

1: y gracias! –

+0

+1 y muchas gracias, nunca supe que esto existía, ¡pero lo necesito esta noche! – dadwithkids

3

Esta fue la solución que se me ocurrió que incluía las respuestas Keeper y Ersatz. El sistema no permitiría que vote ustedes arriba sin embargo :(

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

Esto permitió que algunos resultados sorprendentes

+0

Si usa CONCAT_WS y el separador (primer argumento) no es NULO, no es necesario utilizar IFNULL. '" CONCAT_WS() no omite cadenas vacías. Sin embargo, omite cualquier valor NULL después del argumento separador. Si el separador es NULL, el resultado es NULL. "' Ver http://dev.mysql.com/doc/ refman/5.0/es/string-functions.html # function_concat-ws – dvb

1

Ésta es una respuesta basada en la solución anterior por @chocojosh y otra pregunta aquí: MySQL/SQL: Update with correlated subquery from the updated table itself

Tuve un problema similar, pero estaba intentando combinar un grupo de group_concats y algunos eran NULL, lo que causaba que toda la fila fuera NULL. El objetivo era colocar datos de otras tablas en un solo campo en la tabla principal para permitir búsquedas de texto completo.

Aquí está el SQL que funcionó. Tenga en cuenta el primer parámetro para concat_ws que hice '', esto permitió espacios entre los valores para el campo de texto completo.

Espero que esto ayude a alguien.

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 
1

usted podría también la función COALESCE() para devolver el primer valor no nulo. De este modo:

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

Esto también sólo puso un espacio si no había ningún nombre medio y un espacio antes y después si había un segundo nombre.

de referencia para esta función se puede encontrar en: http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce

+0

Esta es la mejor respuesta IMO ya que puede unir fácilmente un nulo en una cadena vacía: concat (dirección1, '', coalescencia (unidad, ''), ' ', ciudad,', ', estado,' ', zip) como dirección – Jage