MySQL - Comparar filas

 
Vista:
Imágen de perfil de statham
Val: 86
Ha mantenido su posición en MySQL (en relación al último mes)
Gráfica de MySQL

Comparar filas

Publicado por statham (34 intervenciones) el 22/04/2019 11:17:28
Buenas gente como vais?

Bueno como siempre al lio!

Quiero comparar 2 filas de una misma tabla(y en el caso de este ejemplo, que tengan misma raza), y la fila que tenga un campo en null se rellene con la otra, ejemplo:

Tabla A
id nombre raza peso altura
1 rex pastor aleman 30 1
2 boby pastor aleman null/vacio 1

Intento sacar que la fila con el id 2 se rellene el campo peso que esta a null, con 30 que es el de id 1 y son de la misma raza.

La cosa se me complica, por que en este caso se que el campo que esta a null es peso, pero eso no deberia saberse, por tanto tendria que ir columna a columna comprobando si es null y si lo es, buscar otro perro de su misma raza y rellenar con sus datos los que tenga a null.
(hay alguna manera de forzar a comprobar todos los campos de un registro sin tener que ponerlos todos en el select para que vay uno por uno?)
Como lo hariais?funcion con cursor? consulta con update?

Un saludo!
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
1
Responder
Imágen de perfil de Vega
Val: 69
Ha mantenido su posición en MySQL (en relación al último mes)
Gráfica de MySQL

Comparar filas

Publicado por Vega (30 intervenciones) el 23/04/2019 23:08:21
Así a lo bruto un poco, yo lo intentaría con algo así:
usando coalesce () con cada columna.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
with Tabla_A  as (
 
select id = 1,nombre = 'rex', raza = 'pastor aleman', Peso =  30 , altura= 1 union all
select 2 ,'boby', 'pastor aleman'  , null , 1
)
select a.id
,		a.nombre
,		coalesce(a.peso, b.peso) as Peso
,		coalesce(a.altura, c.altura) as Altura
 
 from Tabla_A A
 --para Peso
left join (select raza, peso from Tabla_A where peso is not null) B on a.raza = b.raza
 
-- para Altura
left join (select raza, avg(altura) as altura from Tabla_A where altura is not null group by raza) c on a.raza = b.raza
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de statham
Val: 86
Ha mantenido su posición en MySQL (en relación al último mes)
Gráfica de MySQL

Comparar filas

Publicado por statham (34 intervenciones) el 24/04/2019 09:08:29
Claro, pero el ejemplo que puse es sencillo, mi tabla tendrá unas 15 columnas.
Tendría que poner todas en el select? por que tampoco se cual esta en nulo y cual no.
Podrías explicar por encima por que lo haces así?
coalesce() devuelve el primer valor nulo, pero tendríamos que comprobar todas las columnas con dicha función.
De todas formas gracias y un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Vega
Val: 69
Ha mantenido su posición en MySQL (en relación al último mes)
Gráfica de MySQL

Comparar filas

Publicado por Vega (30 intervenciones) el 24/04/2019 11:26:42
Con respecto a tu pregunta: Como lo hariais?funcion con cursor? consulta con update?

Cursores = horrores :D so horribles, en situaciones muy concretas son excepcionalmente útiles, pero siempre tiene que andar uno con precaución.

Función, pichi-picha... si pero - posiblemente en conjunto con una sentencia INSERT. Posiblemente útil en el caso de que estés introduciendo una sola fila durante la inserción de un registro nuevo.

Update, si - directamente como forma de eliminar un problema con los registros de tu tabla.

Lo que pasa, como bien entenderás, es que no hay una respuesta única y todo depende del problema en su totalidad...

La cuestión también es: ¿Cómo han llegado a estar presentes estos registros con atributos nulos? La aplicación que maneja el formulario que usas para introducir los datos debería ser capaz de evitar este problema a-priori, a menos que esto se trate de una situación muy particular como por ejemplo que estés cargando un fichero de datos y estás limpiando los campos. En tal caso, y sabiendo que tienes un listado de columnas discreto, encadenaría un left join en función del número de columnas que tengas. Si son 15 columnas, pues 15 LEFT JOIN´s.

Otra manera, y mucho más eficaz, de limpiar los atributos nulos sería definir un valor predeterminado para cada campo dentro de un left join y luego usarlo con el coalesce. De esta manera, cuando un NULL se presenta en cada uno de los campos, el coalesce lo completa con el valor perteneciente a la consulta del conjunto derivado del LEFT JOIN.


Lo intento explicar quedaría algo así:
1
2
3
4
5
6
7
8
9
10
11
12
select     a.id
,		coalesce(a.nombre, b.nombre) AS Nombre
,		coalesce(a.peso, b.peso) as Peso
,		coalesce(a.altura, c.altura) as Altura
 from Tabla_A A
-- valores por defecto
left join (select raza
               ,           'SinNombre' as Nombre
               ,           AVG(peso) as Peso
               ,           AVG(altura) as altura
               ,           from Tabla_A where
               ,           group by raza) c on a.raza = b.raza
En la solución que te propongo:
- los campos numéricos, propongo calcular una media de Peso y Altura por cada raza
- el left join lo hacemos en campo de raza como has explicado.
- el coalesce es simplemente una manera perezosa de crear una cláusula CASE.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar