MySQL CASE & # 8220; Else Case When & # 8221; se ejecuta cuando la condición previa es verdadera: ¿qué me estoy perdiendo?

StackOverflow https://stackoverflow.com/questions/1620973

  •  06-07-2019
  •  | 
  •  

Pregunta

Tengo una tabla que, debido al sistema de terceros que estamos usando, a veces tiene datos duplicados. Dado que el modelo utiliza un método EAV, no hay forma de filtrar esto con la " derecha " De esta manera, estoy agregando los datos a una vista. Sé que esto es un problema de recopilación de datos, pero es más fácil para mí corregirlos en el extremo de la pantalla que pasar por este sistema y potencialmente romper los datos y formularios existentes. Necesito marcar uno de los dos campos para ver si se ingresó uno o ambos, pero solo seleccione uno (de lo contrario, el nombre se muestra dos veces así: "John, John" en lugar de "John"). Aquí está mi código para la parte relevante:

group_concat(
(
  case when (`s`.`fieldid` = 2) then `s`.`data` 
  else
    case when (`s`.`fieldid` = 35) then `s`.`data` 
    else NULL end 
  end
) separator ','),_utf8'') as first_name

Si se ingresan tanto fieldid 2 como fieldid 35, esperaría que esto solo devuelva el valor de fieldid = 2 y no el valor de fieldid = 35, ya que la cláusula Else no debería ejecutarse cuando el caso original es verdadero . Sin embargo, se está tomando eso y luego se sigue ejecutando el caso cuando está dentro de la cláusula else?

¿Cómo puedo corregir este código para que me proporcione fieldid = 2 O fieldid = 35, pero evito agruparlos juntos, lo que hace que el nombre se duplique?

EDIT

Aquí está la estructura de la tabla:

table: subscribers_data
subscriberid (int)   fieldid (int)   data (text)    

Utiliza una estructura E-A-V por lo que un registro de muestra podría ser:

subscriberid          fieldid         data
1                     2               John
1                     3               Smith
1                     35              John
1                     36              Smith

siendo fieldid 2 y 35 el campo personalizado " Primer nombre " (definido en una tabla separada) y los ID de campo 3 y 36 son " Apellido " ;.

Aquí está la vista completa que estoy usando:

select `ls`.`subscriberid` AS `id`,
left(`l`.`name`,(locate(_utf8'_',`l`.`name`) - 1)) AS `user_id`,
ifnull(group_concat((
    case when (`s`.`fieldid` = 2) then `s`.`data` 
    when (`s`.`fieldid` = 35) then `s`.`data` 
    else NULL end) separator ','),_utf8'') AS `first_name`,
ifnull(group_concat((
    case when (`s`.`fieldid` = 3) then `s`.`data` 
    when (`s`.`fieldid` = 36) then `s`.`data` 
    else NULL end) separator ','),_utf8'') AS `last_name`,
ifnull(`ls`.`emailaddress`,_utf8'') AS `email_address`,
ifnull(group_concat((
    case when (`s`.`fieldid` = 81) then `s`.`data` 
    else NULL end) separator ','),_utf8'') AS `mobile_phone`,
ifnull(group_concat((
    case when (`s`.`fieldid` = 100) then `s`.`data` 
    else NULL end) separator ','),_utf8'') AS `sms_only` 
from ((`list_subscribers` `ls` 
join `lists` `l` on((`ls`.`listid` = `l`.`listid`))) 
left join `subscribers_data` `s` on((`ls`.`subscriberid` = `s`.`subscriberid`))) 
where (left(`l`.`name`,(locate(_utf8'_',`l`.`name`) - 1)) regexp _utf8'[[:digit:]]+') 
group by `ls`.`subscriberid`,`l`.`name`,`ls`.`emailaddress`

La vista se está utilizando como modelo para una aplicación de Ruby on Rails, por lo que estoy usando algo de pirateo creativo para falsificar un " user_id " que Rails espera (nombramos el campo lista.nombre en la tabla de Listas usando un ID numérico que nuestra aplicación Front-end de Rails genera cuando agregamos un nuevo usuario, así que estoy extrayendo solo este número para hacer que la vista se vea como un Rails -tabla de base de datos de convenciones)

¿Fue útil?

Solución

Cualquier cosa dentro de group_concat () no tiene una manera de ver el contexto en el que se está ejecutando. Entonces, tiene dos filas en un solo grupo, una con fieldid = 2 y la segunda con fieldid = 35 , hará lo siguiente:

  • fila de procesamiento con fieldid = 2 ...
    • s.fieldid = 2 es verdadero, devuelve s.data
  • fila de procesamiento con fieldid = 35 ...
    • s.fieldid = 2 es falso, intente con la parte else
    • s.fieldid = 35 es verdadero, devuelve s.data

Esto explica por qué es " John " devuelto varias veces. La única forma de solucionarlo es ejecutar una consulta diferente fuera de group_concat () .

EDIT:

Realmente tienes que hacerlo de esta manera, usa algo como esto en su lugar:

SELECT ...
   min(CASE WHEN s.fieldid IN (2,35) THEN s.data ELSE NULL END) AS first_name
...

Alternativamente, puedes hacer group_concat (DISTINCT ...) si los dos valores no pueden ser diferentes (de lo contrario obtendrías, por ejemplo, " John, Johny "). Sin embargo, ¿por qué tienes dos valores para first_name / last_name?

Otros consejos

No soy un tipo de mysql, pero en una declaración de caso de servidor SQL, podría hacerlo sin el primer 'else'

case
  when fieldid = 2 then data
  when fieldid = 35 then data
  else null
end

Además, parece que estás devolviendo el mismo campo de 'datos' en ambos casos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top