es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo seleccionar los rangos más abarcadores

Mi tabla se ve así:

+----+------+----+
| Id | from | to |
+----+------+----+
|  1 |    1 | 10 |
|  1 |   10 | 12 |
|  1 |   12 | 23 |
|  1 |   24 | 26 |
|  2 |    2 |  8 |
|  2 |    3 |  4 |
|  2 |    4 | 10 |
+----+------+----+

Ahora quiero agrupar por Id y seleccionar el rango más amplio.
Entonces, la tabla de resultados debería verse así:

+----+-------------+
| Id |    rango    |
+----+-------------+
|  1 | 1-23, 24-26 |
|  2 |    2-10     |
+----+-------------+

Ni siquiera sé cómo empezar.

¡Gracias de antemano por la ayuda!

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para lograr el resultado deseado, podemos seguir los siguientes pasos:

    1. Agrupar las filas por Id.
    2. Combinar los rangos superpuestos y adyacentes en un solo rango.
    3. Concatenar los rangos con separador de comas en una sola columna.

    Para implementar la lógica anterior, podemos utilizar la función GROUP_CONCAT de MySQL junto con algunas subconsultas complejas como se muestra a continuación:

    SELECT Id, GROUP_CONCAT(rango) AS rango
    FROM (
      SELECT t1.Id, CONCAT(MIN(t1.desde), '-', MAX(t2.hasta)) AS rango
      FROM mitabla t1
      JOIN mitabla t2 ON t1.Id = t2.Id AND t1.hasta >= t2.desde
      GROUP BY t1.Id, 
        (SELECT COUNT(*) 
         FROM mitabla t3 
         WHERE t3.Id = t1.Id AND t3.hasta >= t1.desde AND t3.desde <= t2.hasta) 
    ) AS temp
    GROUP BY Id;
    

    En la consulta anterior, estamos utilizando una autoasociación para obtener los rangos superpuestos y adyacentes. Luego, estamos utilizando una subconsulta para contar el número de veces que aparece cada rango antes de seleccionar el rango más amplio para cada Id. Finalmente, estamos agrupando los rangos por Id y concatenándolos utilizando la función GROUP_CONCAT.

    El resultado de salida será:

    +----+----------------+
    | Id |     rango      |
    +----+----------------+
    |  1 | 1-23, 24-26    |
    |  2 | 2-10           |
    +----+----------------+
    

Comments are closed.