He hecho una pregunta aquí: /programming/43807566/how-to-divide-two-values-from-the-same-column-but-at-different-rows
sobre dividir valores de la misma tabla, en la misma columna pero en diferentes filas. Ahora tengo el problema donde tengo más numeradores y denominadores (con diferentes uns
). ¿Sigue siendo la self join
mejor manera de resolver este problema con Postgres o hay mejores soluciones?
Ejemplo:
| postcode | value | uns |
|----------|-------|-----|
| AA | 40 | 53 |
| BB | 20 | 53 |
| AA | 10 | 54 |
| AA | 20 | 55 |
| AA | 10 | 56 |
| AA | 30 | 57 |
| AA | 50 | 58 |
| BB | 10 | 54 |
| BB | 10 | 55 |
| BB | 70 | 56 |
| BB | 80 | 57 |
| BB | 10 | 58 |
El resultado debe ser:
| postcode | formula |
|----------|------------|
| AA | 18.888... |
| BB | 14.375 |
Donde los valores se agrupan por código postal y la fórmula es (valor con uns):
(V53 * V56 + V54 * V57 + V55 * V58) / (V56 + V57 + V58)
Prestando atención para evitar la eventual división por cero. La fórmula puede ser aún más compleja, pero ese es un buen ejemplo.
postgresql
pivot
computed-column
Aleatorizar
fuente
fuente
uns
conviertan en nombres de columna; a partir de ahí, cualquier fórmula que use los valores debería ser viable. ¿La fórmula estará codificada o se derivará dinámicamente de alguna manera?Respuestas:
Este es un problema de pivote / tabla cruzada en su núcleo, como Michael ya diagnosticó con precisión.
Si no está familiarizado con el
tablefunc
módulo en Postgres, lea las instrucciones básicas aquí:La consulta se vuelve simple y muy rápida (más rápida que otras soluciones presentadas aquí):
NULLIF
para evitar la división por cero.dbfiddle aquí
fuente
Puede agregar todos los pares uns / value en un objeto JSON, luego usarlo para acceder a los valores UNS por nombre. Esto requiere un poco de conversión ya que los valores solo se pueden extraer como texto del objeto JSON, pero la fórmula se ve muy similar a su descripción entonces:
He dividido la agregación, la evaluación del denominador y el divisor y la división final en tres pasos para que sea más legible.
Ejemplo en línea: http://rextester.com/IZYT54566
Puede simplificar la fórmula creando una función:
fuente
El patrón PIVOT funcionaría para esto. Convierte los valores de las filas en columnas en una sola fila, de acuerdo con su clave común. Hay algunas formas de implementar esto. Algunos requieren solo un escaneo de una sola tabla.
Después del PIVOT, tendría una tabla con una fila por código postal y una columna por valor. El resto de la consulta se escribiría como si hiciera referencia a una sola tabla.
fuente
Suponiendo que
(postcode, uns)
sonUNIQUE
(probablemente, un PK), se puede implementar el patrón PIVOT, como ya comentó @ michael-green, portátil utilizando la siguiente consulta:Compruébelo en SQLFiddle .
fuente
Suponiendo que
(postcode, uns)
sonUNIQUE
(probablemente, un PK), probablemente la forma más simple , probablemente la más portátil, aunque probablemente no sea la óptima: use tantas subselecciones como sea necesario :Verifique en SQLFiddle .
fuente