Я задал вопрос здесь: /programming/43807566/how-to-divide-two-values-from-the-same-column-but-at-different-rows
о делении значений из одной и той же таблицы, в одном столбце, но в разных строках. Теперь у меня есть проблема, где у меня есть больше числителей и знаменателей (с разными uns
). Все еще self join
хороший способ решить эту проблему с Postgres или есть лучшие решения?
Пример:
| 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 |
Результат должен быть:
| postcode | formula |
|----------|------------|
| AA | 18.888... |
| BB | 14.375 |
Где значение сгруппировано по почтовому индексу, а формула (значение с uns):
(V53 * V56 + V54 * V57 + V55 * V58) / (V56 + V57 + V58)
Обратите внимание, чтобы избежать возможного деления на ноль. Формула может быть еще более сложной, но это хороший пример.
postgresql
pivot
computed-column
Randomize
источник
источник
uns
имена столбцов стали - оттуда, любая формула, использующая значения, должна стать работоспособной. Будет ли формула жестко закодирована или как-то получена динамически?Ответы:
По сути, это проблема сводной / кросс-таблицы , как Майкл уже точно диагностировал .
Если вы не знакомы с
tablefunc
модулем в Postgres, прочтите основные инструкции здесь:Запрос становится простым и очень быстрым (быстрее, чем другие решения, представленные здесь):
NULLIF
предотвратить деление на ноль.dbfiddle здесь
источник
Вы можете объединить все пары uns / value в объект JSON, а затем использовать его для доступа к значениям UNS по имени. Это требует некоторого приведения, поскольку значения могут быть извлечены только как текст из объекта JSON, но тогда формула выглядит очень похоже на ваше описание:
Я разделил агрегацию, оценку знаменателя и делителя и окончательное деление на три этапа, чтобы сделать его более читабельным.
Пример в сети: http://rextester.com/IZYT54566
Вы можете упростить формулу, создав функцию:
источник
Модель PIVOT будет работать для этого. Он преобразует значения строк в столбцы в одной строке в соответствии с их общим ключом. Есть несколько способов реализовать это. Некоторые требуют только одного сканирования таблицы.
После PIVOT у вас будет таблица с одной строкой на почтовый индекс и столбцом на значение. Оставшаяся часть запроса будет записана так, как будто она ссылается на одну таблицу.
источник
Предполагая, что
(postcode, uns)
этоUNIQUE
(возможно, PK), шаблон PIVOT, как уже прокомментировал @ michael-green, может быть реализован переносимо с использованием следующего запроса:Проверьте это в SQLFiddle .
источник
Предполагая, что
(postcode, uns)
этоUNIQUE
(возможно, PK), возможно, самый простой способ, возможно, самый переносимый, хотя, вероятно, не оптимальный: используйте столько подвыборов, сколько необходимо :Проверьте в SQLFiddle .
источник