2012-05-16 22 views
5

que tienen un punto de vista que se parece a estoencabezados de columna de transposición a las filas de PostgreSQL

  value1count  value2count value3count 
      ---------------------------------------- 
      25    35   55 

necesito para transponer la cabecera de la columna en filas y así que necesito que se vea como

  Values    Count 
     ----------------------------- 
      value1count   25 
      value2count   35 
      value3count   55 

I puede hacer esto seleccionando nombres de columnas individuales como primera columna y datos como segunda columna y luego hacer una unión de los mismos para todas las columnas.

¿Hay una mejor manera de hacerlo? Estoy usando PosgreSQL 8.1 y por lo tanto no tengo operadores de pivote para trabajar.

Gracias por su respuesta con anticipación.

+0

sí estamos actualizando a la última version..probably a finales de verano .... Gracias – cableload

+0

Columnas así (y preguntas por el estilo) suelen indicar un diseño defectuoso. Usted menciona una VISTA involucrada, por lo que podría no ser el caso con sus tablas. Pero considere un rediseño si esa vista refleja la estructura de la tabla real –

Respuesta

22

Tabla cruzada solamente hace lo contrario de lo que necesita, pero esto le ayudará a:

En primer lugar crear la función unnest() que se incluye en 8.4, ver here para obtener instrucciones.

A continuación, puede hacer esto (basado en this post):

SELECT 
    unnest(array['value1Count', 'value2Count', 'value3Count']) AS "Values", 
    unnest(array[value1Count, value2Count, value3Count]) AS "Count" 
FROM view_name 
ORDER BY "Values" 

puedo comprobar que esto funciona en 8.4, pero debido a que no tengo 8.1, no puedo prometer que va a funcionar el mismo.

+2

Esto es brillante ... trabajó bien en 8.1 ... mi consulta sindical tardó 10 segundos y esta única consulta tardó solo 3 segundos ... Gracias PinnyM. – cableload

5

que logra su objetivo mediante el uso de hstore 's funcionalidades:

SELECT (x).key, (x).value 
FROM 
    (SELECT EACH(hstore(t)) as x 
    FROM t 
) q; 

le puede haber múltiples filas de la 'a-ser-explotado' vista o tabla (denominada aquí como t), es posible que necesite insertar un identificador additionnal en la mesa intermedia q, por ejemplo:

SELECT id, (x).key, (x).value 
FROM 
    (SELECT id, EACH(hstore(t)) as x 
    FROM t 
) q; 

Referencia: hstore documentation

+0

+1, la ventaja aquí es evitar la necesidad de nombrar sus columnas en su consulta. Aparentemente [no funciona tan bien como unnest] (http://www.postgresonline.com/journal/archives/283-Unpivoting-data-in-PostgreSQL.html), pero no en un grado significativo. – PinnyM

+0

¡Esta es una solución brillante, gracias! El único problema es que el orden de las columnas se arruina. ¿Tienes alguna idea de cómo solucionarlo? – David

3

Estaba buscando hacer algo similar a esto para procesar más fácilmente la información de la tabla desde un script bash. Resulta ser muy fácil decir psql para mostrar las columnas de la tabla como filas:

psql mydbname -x -A -F= -c "select * from blah where id=123" 
  • El -x es lo que pivota la salida.
  • El -A elimina el espaciado adicional.
  • El -F= reemplaza | con = entre el nombre de columna y el valor.

Esto, por supuesto, no funciona en SQL, solo modifica la forma en que psql pasa a formatear la salida.

0

Tuve una situación similar. Envolví mi consulta en una declaración con y luego hice un montón de UNION ALL s para cada fila. En mi situación, si tuviera varios registros, el ncm_id sería diferente, así que seguí adelante y lo agregué a mi lista de columnas en mi conjunto de resultados. Puede que esta no sea la mejor manera de hacerlo, pero funcionó para mi caso de uso.

WITH query_a AS (
    SELECT 
     fin_item.item_number || ' - ' || fin_item.item_descrip1 fin_item, 
     fin_ls.ls_number, 
     ls_sort.sortby_employeeid, 
     ls_sort.ncm_id, 
     ls_sort.created_at, 
     ls_sort.updated_at, 
     ls_sort.sort_qty, 
     ls_sort.initial_scan_time, 
     ls_sort.ncm_scan_time, 
     ls_sort.badge_scan_time, 
     ls_sort.computer_name, 
     ls_sort.number_of_ops, 
     ls_sort.ncm_item_scan_time, 
     sort_by.name sort_by, 
     tblncm.instructions, 
     tblncm.ncm_comments 
    FROM public.item AS fin_item 
     INNER JOIN public.ls AS fin_ls ON fin_item.item_id = fin_ls.ls_item_id 
     INNER JOIN stone.ls_sort ON fin_ls.ls_id = ls_sort.ls_id 
     INNER JOIN stone.vw_mssql_employees AS sort_by ON ls_sort.sortby_employeeid = sort_by.employeeid 
     INNER JOIN stone.tblncm ON ls_sort.ncm_id = tblncm.ncm_id 
     LEFT JOIN stone.equips AS mach_equips ON ls_sort.mach_equip_id = mach_equips.id 
     LEFT JOIN stone.equips AS mold_equips ON ls_sort.mold_equip_id = mold_equips.id 
    WHERE 1 = 1 
      AND fin_ls.ls_number ILIKE 'S143027526190' || '%' 
) 
    SELECT * 
    FROM (
    (SELECT 'fin_item' my_column, fin_item::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'ls_number' my_column, ls_number::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'sortby_employeeid' my_column, sortby_employeeid::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'ncm_id' my_column, ncm_id::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'created_at' my_column, created_at::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'updated_at' my_column, updated_at::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'sort_qty' my_column, sort_qty::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'initial_scan_time' my_column, initial_scan_time::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'ncm_scan_time' my_column, ncm_scan_time::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'badge_scan_time' my_column, badge_scan_time::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'computer_name' my_column, computer_name::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'number_of_ops' my_column, number_of_ops::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'ncm_item_scan_time' my_column, ncm_item_scan_time::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'sort_by' my_column, sort_by::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'instructions' my_column, instructions::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
     UNION ALL 
    (SELECT 'ncm_comments' my_column, ncm_comments::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a) 
    ) as query_guy 
ORDER BY my_ncm; 
Cuestiones relacionadas