Digamos que tengo una tabla simple agg_test con 3 columnas – id, column_1 y column_2. Conjunto de datos, por ejemplo:

id|column_1|column_2
--------------------
 1|       1|       1
 2|       1|       2
 3|       1|       3
 4|       1|       4
 5|       2|       1
 6|       3|       2
 7|       4|       3
 8|       4|       4
 9|       5|       3
10|       5|       4 

Una consulta como esta (con self join):

SELECT
  a1.column_1,
  a2.column_1,
  ARRAY_AGG(DISTINCT a1.column_2 ORDER BY a1.column_2)
FROM agg_test a1
JOIN agg_test a2 ON a1.column_2 = a2.column_2 AND a1.column_1 <> a2.column_1
WHERE a1.column_1 = 1
GROUP BY a1.column_1, a2.column_1

Va a producir un resultado como este:

column_1|column_1|array_agg
---------------------------
       1|       2|      {1}
       1|       3|      {2}
       1|       4|    {3,4}
       1|       5|    {3,4}

Podemos ver que para valores 4 y 5 de la tabla combinada tenemos el mismo resultado en la última columna. Por lo tanto, es posible de alguna manera agrupar los resultados por él, e.g:

column_1|column_1|array_agg
---------------------------
       1|     {2}|      {1}
       1|     {3}|      {2}
       1|   {4,5}|    {3,4}

Gracias por la respuestas. Si algo no está claro o puede ser presentada en una forma mejor – me dicen en los comentarios y trataré de hacer esta pregunta tan legible como puedo.

InformationsquelleAutor Przemek | 2013-03-27

2 Comentarios

  1. 4

    No estoy seguro de si se puede agregar por una matriz. Si usted puede aquí es un enfoque:

    select col1, array_agg(col2), ar
    from (SELECT a1.column_1 as col1, a2.column_1 as col2,
                 ARRAY_AGG(DISTINCT a1.column_2 ORDER BY a1.column_2) as ar
          FROM agg_test a1 JOIN
               agg_test a2
               ON a1.column_2 = a2.column_2 AND a1.column_1 <> a2.column_1
          WHERE a1.column_1 = 1
          GROUP BY a1.column_1, a2.column_1
         ) t
    group by col1, ar

    La alternativa es utilizar array_dims para convertir los valores de la matriz en una cadena.

    • Gracias, funciona a la perfección para mí.
  2. 2

    También puedes probar algo como esto:

    SELECT DISTINCT
      a1.column_1,
      ARRAY_AGG(a2.column_1) OVER (
        PARTITION BY
          a1.column_1,
          ARRAY_AGG(DISTINCT a1.column_2 ORDER BY a1.column_2)
      ) AS "a2.column_1 agg",
      ARRAY_AGG(DISTINCT a1.column_2 ORDER BY a1.column_2)
    FROM agg_test a1
    JOIN agg_test a2 ON a1.column_2 = a2.column_2 AND a1.column_1  a2.column_1
    WHERE a1.column_1 = 1
    GROUP BY a1.column_1, a2.column_1
    ;

    (Resaltado son las partes que son diferentes de la consulta que se ha publicado en su pregunta.)

    El anterior utiliza una ventana ARRAY_AGG para combinar los valores de a2.column_1 junto al resto de los otros ARRAY_AGG, el uso de este último resultado como uno de los criterios de partición. Sin DISTINCT, produciría dos {4,5} filas por su ejemplo. Así, DISTINCT es necesaria para eliminar los duplicados.

    Aquí un SQL Violín demo: http://sqlfiddle.com/#!1/df5c3/4

    Nota, sin embargo, que la ventana ARRAY_AGG puede tener un ORDER BY como es «normal» contraparte. Esto significa que el orden de a2.column_1 valores en la lista sería indeterminado, aunque en el vinculado demo sucede para que coincida con el de su salida esperada.

Dejar respuesta

Please enter your comment!
Please enter your name here