Sort values of the columns from largest to smallest in an array and save each ordered value in a new variable

1

The data in the blue box exists, the data in the red box must be registered,

It is to order the (data from the blue box) from largest to smallest and pass them to the column of the red box, according to their order.

What I have done so far:

                CREATE DEFINER = 'root'@'localhost'
                PROCEDURE PLANILLA_ROTACIONES_25_O01()
                BEGIN


                  declare TOT_M_01 INT (20);
                  declare TOT_M_02 INT (20);
                  declare TOT_M_03 INT (20);
                  declare TOT_M_04 INT (20);
                  declare TOT_M_05 INT (20);
                  declare TOT_M_06 INT (20);
                  declare TOT_M_07 INT (20);
                  declare TOT_M_08 INT (20);
                  declare TOT_M_09 INT (20);
                  declare TOT_M_10 INT (20);
                  declare TOT_M_11 INT (20);
                  declare TOT_M_12 INT (20);


                  DECLARE no_hay_mas_registros INT DEFAULT 0; 
                  DECLARE elCursor CURSOR FOR SELECT CODIGO  FROM PLANILLA_ROTACIONES ;





                      open elCursor;
                      -- se van tomando los datos hasta que el cursor llegue al final
                      bucle: loop

                      fetch elCursor into codigo_new;
                        if (no_hay_mas_registros = 1) then
                            leave bucle;
                        end if;

                      // comentario: aca tomo el datoy lo guardo en una variable
                      SET TOT_M_01 = (SELECT TOTAL_M_01 FROM planilla_rotaciones WHERE CODIGO=codigo_new); 
                      SET TOT_M_02 = (SELECT TOTAL_M_02 FROM planilla_rotaciones WHERE CODIGO=codigo_new);
                      SET TOT_M_03 = (SELECT TOTAL_M_03 FROM planilla_rotaciones WHERE CODIGO=codigo_new);
                      SET TOT_M_04 = (SELECT TOTAL_M_04 FROM planilla_rotaciones WHERE CODIGO=codigo_new);
                      SET TOT_M_05 = (SELECT TOTAL_M_05 FROM planilla_rotaciones WHERE CODIGO=codigo_new);
                      SET TOT_M_06 = (SELECT TOTAL_M_06 FROM planilla_rotaciones WHERE CODIGO=codigo_new);
                      SET TOT_M_07 = (SELECT TOTAL_M_07 FROM planilla_rotaciones WHERE CODIGO=codigo_new);
                      SET TOT_M_08 = (SELECT TOTAL_M_08 FROM planilla_rotaciones WHERE CODIGO=codigo_new);
                      SET TOT_M_09 = (SELECT TOTAL_M_09 FROM planilla_rotaciones WHERE CODIGO=codigo_new);
                      SET TOT_M_10 = (SELECT TOTAL_M_10 FROM planilla_rotaciones WHERE CODIGO=codigo_new);
                      SET TOT_M_11 = (SELECT TOTAL_M_11 FROM planilla_rotaciones WHERE CODIGO=codigo_new);
                      SET TOT_M_12 = (SELECT TOTAL_M_12 FROM planilla_rotaciones WHERE CODIGO=codigo_new);



                      CREATE TEMPORARY TABLE IF NOT EXISTS Temporal AS (
                       SELECT CODIGO, 
                       GROUP_CONCAT(TOT_M_01,
                                    TOT_M_02,
                                    TOT_M_03,
                                    TOT_M_04,
                                    TOT_M_05,
                                    TOT_M_06,
                                    TOT_M_07,
                                    TOT_M_08,
                                    TOT_M_09,
                                    TOT_M_10,
                                    TOT_M_11,
                                    TOT_M_12
                       order by Columnas DESC) ColumnasOrdenadas
                       FROM ( SELECT  CODIGO,
                                   (case when n = 1 then TOTAL_M_01
                                         when n = 2 then TOTAL_M_02
                                         when n = 3 then TOTAL_M_03
                                         when n = 4 then TOTAL_M_04
                                         when n = 5 then TOTAL_M_05
                                         when n = 6 then TOTAL_M_06
                                         when n = 7 then TOTAL_M_07
                                         when n = 8 then TOTAL_M_08
                                         when n = 9 then TOTAL_M_09
                                         when n = 10 then TOTAL_M_10
                                         when n = 11 then TOTAL_M_11
                                         when n = 12 then TOTAL_M_12
                                    end
                                   ) as Columnas
                        from PLANILLA_ROTACIONES a 
                        cross join (select 1 as n union all select 2 
                                                  union all select 3 
                                                  union all select 3 
                                                  union all select 4
                                                  union all select 5 
                                                  union all select 6 
                                                  union all select 7 
                                                  union all select 8
                                                  union all select 9 
                                                  union all select 10 
                                                  union all select 11 
                                                  union all select 12) n
                    ) T
                    GROUP BY CODIGO
                );





                     IF (SELECT count(CODIGO) as conteo from PLANILLA_ROTACIONES WHERE  CODIGO  = codigo_new ) = 1 THEN 




                         UPDATE PLANILLA_ROTACIONES  E
                         INNER JOIN Temporal T ON E.CODIGO = T.CODIGO
                         SET o_01 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 1), ',', -1),UNSIGNED INTEGER),
                             o_02 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 2), ',', -1),UNSIGNED INTEGER),
                             o_03 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 3), ',', -1),UNSIGNED INTEGER),
                             o_04 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 4), ',', -1),UNSIGNED INTEGER),
                             o_05 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 5), ',', -1),UNSIGNED INTEGER),
                             o_06 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 6), ',', -1),UNSIGNED INTEGER),
                             o_07 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 7), ',', -1),UNSIGNED INTEGER),
                             o_08 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 8), ',', -1),UNSIGNED INTEGER),
                             o_09 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 9), ',', -1),UNSIGNED INTEGER),
                             o_10 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 10), ',', -1),UNSIGNED INTEGER),
                             o_11 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 11), ',', -1),UNSIGNED INTEGER),
                             o_12 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 12), ',', -1),UNSIGNED INTEGER);


                      END IF;





                    end loop bucle;
                  close elCursor;



                END

I need ideas on how I could make this arrangement from major to minor, if you can help me I would appreciate it.

    
asked by Francisco Acevedo 30.07.2018 в 23:13
source

1 answer

1

Although I do not know in depth MySQL I understand that what you are looking for is not easy to solve from SQL. No doubt this is a task that you should leave in the hands of the "front-end". Even so, if you must solve it from the database, what I can think of to do is the following:

  • Transpose the columns of interest in new rows (this to be able to order)
  • Concatenate all columns (separated by , ) in a single row for each ID original and sorted by the value
  • Update the new columns of the original table with the result of the previous step
  • Basically at a conceptual level, now I present a simple example, which you should adapt to your data structure, it is essential that you have a ID per row, it can be an existing one or eventually you should generate a new one. The example is only with 3 columns to make it easy to understand.

    First, we create a table of Example

    create table Ejemplo (
      ID    INT,
      TOTAL_M_01  INT,
      TOTAL_M_02  INT,
      TOTAL_M_03  INT,
      O_01 INT,
      O_02 INT,
      O_03 INT
    );
    
    INSERT INTO Ejemplo (ID, TOTAL_M_01, TOTAL_M_02, TOTAL_M_03) values (1,3,5,1);
    INSERT INTO Ejemplo (ID, TOTAL_M_01, TOTAL_M_02, TOTAL_M_03) values (2,2,6,7);
    INSERT INTO Ejemplo (ID, TOTAL_M_01, TOTAL_M_02, TOTAL_M_03) values (3,6,1,3);
    
    +---+----+------------+------------+------------+------+------+------+
    | # | ID | TOTAL_M_01 | TOTAL_M_02 | TOTAL_M_03 | O_01 | O_02 | O_03 |
    +---+----+------------+------------+------------+------+------+------+
    | 1 | 1  | 3          | 5          | 1          | NULL | NULL | NULL |
    +---+----+------------+------------+------------+------+------+------+
    | 2 | 2  | 2          | 6          | 7          | NULL | NULL | NULL |
    +---+----+------------+------------+------------+------+------+------+
    | 3 | 3  | 6          | 1          | 3          | NULL | NULL | NULL |
    +---+----+------------+------------+------------+------+------+------+
    

    The idea is to update the columns O_01 to O_03 with the ordered values of the columns TOTAL_M_* .

    Create temporary with the values ordered, concatenated and separated by ,

    CREATE TEMPORARY TABLE IF NOT EXISTS Temporal AS (
    SELECT ID, 
           GROUP_CONCAT(Columnas order by Columnas DESC) ColumnasOrdenadas
           FROM ( SELECT  ID,
                       (case when n = 1 then TOTAL_M_01
                             when n = 2 then TOTAL_M_02
                             when n = 3 then TOTAL_M_03
                        end
                       ) as Columnas
            from Ejemplo a 
            cross join (select 1 as n union all select 2 union all select 3) n
        ) T
        GROUP BY ID
    );
    
    +---+----+-------------------+
    | # | ID | ColumnasOrdenadas |
    +---+----+-------------------+
    | 1 | 1  | 5,3,1             |
    +---+----+-------------------+
    | 2 | 2  | 7,6,2             |
    +---+----+-------------------+
    | 3 | 3  | 6,3,1             |
    +---+----+-------------------+
    

    We already have for each original row, the values of the original columns ordered, now we only have to update the original table

    Update the new columns

    UPDATE Ejemplo E
           INNER JOIN Temporal T
               ON E.ID = T.ID
           SET O_01 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 1), ',', -1),UNSIGNED INTEGER),
               O_02 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 2), ',', -1),UNSIGNED INTEGER),
               O_03 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 3), ',', -1),UNSIGNED INTEGER);
    

    And now we can see the final result:

    +---+----+------------+------------+------------+------+------+------+
    | # | ID | TOTAL_M_01 | TOTAL_M_02 | TOTAL_M_03 | O_01 | O_02 | O_03 |
    +---+----+------------+------------+------------+------+------+------+
    | 1 | 1  | 3          | 5          | 1          | 5    | 3    | 1    |
    +---+----+------------+------------+------------+------+------+------+
    | 2 | 2  | 2          | 6          | 7          | 7    | 6    | 2    |
    +---+----+------------+------------+------------+------+------+------+
    | 3 | 3  | 6          | 1          | 3          | 6    | 3    | 1    |
    +---+----+------------+------------+------------+------+------+------+
    

    to try, you have this Fiddle

    One more help

    I will not go into how a stored procedure is defined and if you are doing it right or not, because it is not part of the question and I am not clear about it, what I can tell you is that this solution does NOT You need the cursor for nothing, delete all that part. The only code you would need is the one that you have already adapted from my answer.

    -- Creamos y completamos la tabla temporal
    CREATE TEMPORARY TABLE IF NOT EXISTS Temporal AS (
           SELECT CODIGO, 
           GROUP_CONCAT(TOT_M_01,
                        TOT_M_02,
                        TOT_M_03,
                        TOT_M_04,
                        TOT_M_05,
                        TOT_M_06,
                        TOT_M_07,
                        TOT_M_08,
                        TOT_M_09,
                        TOT_M_10,
                        TOT_M_11,
                        TOT_M_12
           order by Columnas DESC) ColumnasOrdenadas
           FROM ( SELECT  CODIGO,
                       (case when n = 1 then TOTAL_M_01
                             when n = 2 then TOTAL_M_02
                             when n = 3 then TOTAL_M_03
                             when n = 4 then TOTAL_M_04
                             when n = 5 then TOTAL_M_05
                             when n = 6 then TOTAL_M_06
                             when n = 7 then TOTAL_M_07
                             when n = 8 then TOTAL_M_08
                             when n = 9 then TOTAL_M_09
                             when n = 10 then TOTAL_M_10
                             when n = 11 then TOTAL_M_11
                             when n = 12 then TOTAL_M_12
                        end
                       ) as Columnas
            from PLANILLA_ROTACIONES a 
            cross join (select 1 as n union all select 2 
                                      union all select 3 
                                      union all select 3 
                                      union all select 4
                                      union all select 5 
                                      union all select 6 
                                      union all select 7 
                                      union all select 8
                                      union all select 9 
                                      union all select 10 
                                      union all select 11 
                                      union all select 12) n
        ) T
        GROUP BY CODIGO
    );
    
    
    -- Para verificar antes de actualizar 
    -- correr solo hasta este select
    SELECT CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 1), ',', -1),UNSIGNED INTEGER),
           CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 2), ',', -1),UNSIGNED INTEGER),
           CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 3), ',', -1),UNSIGNED INTEGER),
           CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 4), ',', -1),UNSIGNED INTEGER),
           CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 5), ',', -1),UNSIGNED INTEGER),
           CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 6), ',', -1),UNSIGNED INTEGER),
           CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 7), ',', -1),UNSIGNED INTEGER),
           CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 8), ',', -1),UNSIGNED INTEGER),
           CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 9), ',', -1),UNSIGNED INTEGER),
           CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 10), ',', -1),UNSIGNED INTEGER),
           CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 11), ',', -1),UNSIGNED INTEGER),
           CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 12), ',', -1),UNSIGNED INTEGER)
           FROM PLANILLA_ROTACIONES  E
           INNER JOIN Temporal T ON E.CODIGO = T.CODIGO
    
    
    -- Si los resultados son los eperados podremos actualizar las tablas definitivas
    UPDATE PLANILLA_ROTACIONES  E
           INNER JOIN Temporal T ON E.CODIGO = T.CODIGO
           SET o_01 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 1), ',', -1),UNSIGNED INTEGER),
               o_02 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 2), ',', -1),UNSIGNED INTEGER),
               o_03 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 3), ',', -1),UNSIGNED INTEGER),
               o_04 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 4), ',', -1),UNSIGNED INTEGER),
               o_05 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 5), ',', -1),UNSIGNED INTEGER),
               o_06 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 6), ',', -1),UNSIGNED INTEGER),
               o_07 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 7), ',', -1),UNSIGNED INTEGER),
               o_08 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 8), ',', -1),UNSIGNED INTEGER),
               o_09 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 9), ',', -1),UNSIGNED INTEGER),
               o_10 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 10), ',', -1),UNSIGNED INTEGER),
               o_11 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 11), ',', -1),UNSIGNED INTEGER),
               o_12 = CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(T.ColumnasOrdenadas, ',', 12), ',', -1),UNSIGNED INTEGER);
    
        
    answered by 31.07.2018 в 05:59