TransWikia.com

ordenar filas en columnas en postgresql

Stack Overflow en español Asked by Angel Gutierrez on February 6, 2021

Tengo una tabla donde guardo seguimientos de evaluaciones nutricionales de personas, cada persona puede tener entre 1 a 6 evaluaciones y todas se almacenan es dicha tabla, lo que quiero hacer es que momento de descargar esta información me traiga los datos de la persona 1 vez pero el resultado de cada visita sea el que se agrega por ejemplo

nombre|apellido|telefono|fecha_evaluacion|resultado_evaluacion
pedro |perez   |5558877 | 05/05/2017     | desnutricion
pedro |perez   |5558877 | 05/07/2017     | adecuado

y necesito que me lo regrese de la siguiente forma

nombre|apellido|telefono|fecha_evaluacion1|resultado_evaluacion1|fecha_evaluacion2 | resultado_evaluacion2
pedro | perez  |5558877 |  05/05/2017     | desnutricion        | 05/07/2017       | Adecuado

cada persona puede tener hasta 6 evaluaciones y solo me interesa repetir la fecha de cada evaluacion y su diagnostico.

3 Answers

Una forma posible es numerar cada evaluación de 1 a n (siendo n un número máximo fijo, según mencionas 6) y luego hacer un GROUP BY combinado con alguna función de agregación condicional. Te muestro un ejemplo en base a los datos que aportaste dónde solo tendrías dos juegos de columnas a transponer, pero no es difícil adaptarlo a una mayor cantidad:

Creamos en primer lugar los datos:

CREATE TABLE Ejemplo (
  nombre                  VARCHAR(255),
  apellido                VARCHAR(255),
  telefono                VARCHAR(255),
  fecha_evaluacion        DATE,
  resultado_evaluacion    VARCHAR(255)
);

INSERT INTO Ejemplo (nombre, apellido, telefono, fecha_evaluacion, resultado_evaluacion)
VALUES ('pedro','perez','5558877', '05/05/2017', 'desnutricion'),
       ('pedro','perez','5558877', '05/07/2017', 'adecuado');

Y aquí la consulta:

SELECT M.nombre, 
       M.apellido,
       MAX(CASE WHEN M.Nro = 1 THEN fecha_evaluacion ELSE NULL END)     AS Fecha1,
       MAX(CASE WHEN M.Nro = 1 THEN resultado_evaluacion ELSE NULL END) AS Resultado1,
       MAX(CASE WHEN M.Nro = 2 THEN fecha_evaluacion ELSE NULL END)     AS Fecha2,
       MAX(CASE WHEN M.Nro = 2 THEN resultado_evaluacion ELSE NULL END) AS Resultado2
       FROM ( SELECT nombre, 
                     apellido, 
                     fecha_evaluacion, 
                     resultado_evaluacion,
                     ROW_NUMBER() OVER (PARTITION BY nombre, apellido ORDER BY fecha_evaluacion) AS Nro
                     FROM Ejemplo
       ) M
       GROUP BY M.nombre, 
                M.apellido;

La salida:

+--------+----------+------------+--------------+------------+------------+
| nombre | apellido | fecha1     | resultado1   | fecha2     | resultado2 |
+--------+----------+------------+--------------+------------+------------+
| pedro  | perez    | 2017-05-05 | desnutricion | 2017-05-07 | adecuado   |
+--------+----------+------------+--------------+------------+------------+

Answered by Patricio Moracho on February 6, 2021

Tal vez puedas intentar algo como esto

select *
from crosstab (
    'select id, name, value
    from tt1
    order by 1,2')
AS (row_name int, col1 text, col2 text, col3 text, col4 text);

Donde puedes seleccionar los rows que deseas en forma de columnas

Answered by Emilio Duarte on February 6, 2021

Su base de datos debería ser de dos entidades(tablas), una "personas" y otra "seguimientos." Al intentar mostrar dos columnas por cada seguimiento, tiene que tener en cuenta que usted debe definir las dos columnas, ya que SQL no puede crear columnas por si sola. Entonces si usted quiere mostrar los seis seguimientos, debe definir las demás columnas que quiere mostrar, en este caso serían 12 y la consulta básicamente sería la siguiente.

      SELECT p.nombre, p.apellido, p.telefono,
      (SELECT se.fecha_evaluacion FROM seguimientos se WHERE se.id_persona=p.id_persona LIMIT 0,1) AS fecha_evaluacion1,
      (SELECT se.resultado_evaluacion FROM seguimientos se WHERE se.id_persona=p.id_persona LIMIT 0,1) AS resultado_evaluacion1,
      (SELECT se.fecha_evaluacion FROM seguimientos se WHERE se.id_persona=p.id_persona LIMIT 1,1) AS fecha_evaluacion2,
      (SELECT se.resultado_evaluacion FROM seguimientos se WHERE se.id_persona=p.id_persona LIMIT 1,1) AS resultado_evaluacion2,
      (SELECT se.fecha_evaluacion FROM seguimientos se WHERE se.id_persona=p.id_persona LIMIT 2,1) AS fecha_evaluacion3,
      (SELECT se.resultado_evaluacion FROM seguimientos se WHERE se.id_persona=p.id_persona LIMIT 2,1) AS resultado_evaluacion3,
      (SELECT se.fecha_evaluacion FROM seguimientos se WHERE se.id_persona=p.id_persona LIMIT 3,1) AS fecha_evaluacion4,
      (SELECT se.resultado_evaluacion FROM seguimientos se WHERE se.id_persona=p.id_persona LIMIT 3,1) AS resultado_evaluacion4,
      (SELECT se.fecha_evaluacion FROM seguimientos se WHERE se.id_persona=p.id_persona LIMIT 4,1) AS fecha_evaluacion5,
      (SELECT se.resultado_evaluacion FROM seguimientos se WHERE se.id_persona=p.id_persona LIMIT 4,1) AS resultado_evaluacion5,
      (SELECT se.fecha_evaluacion FROM seguimientos se WHERE se.id_persona=p.id_persona LIMIT 5,1) AS fecha_evaluacion6,
      (SELECT se.resultado_evaluacion FROM seguimientos se WHERE se.id_persona=p.id_persona LIMIT 5,1) AS resultado_evaluacion6,
      FROM personas p INNER JOIN seguimientos s ON(p.id_persona=s.id_persona)
      GROUP BY p.nombre, p.apellido, p.telefono

Answered by Jonathan ch on February 6, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP