Рассчитать процентное изменение между двумя столбцами

У меня есть таблица с двумя столбцами, в которых указано количество определенного элемента на выпуск нашего продукта. Мне нужно рассчитать процентное увеличение между двумя столбцами и добавить его в новый столбец в таблице, однако я не нашел никакой документации, относящейся к этому? Я использую Postgres 9.0, и мне нужно изучить процентное увеличение между двумя столбцами в рамках процесса контроля качества, чтобы убедиться, что между выпусками нет отсутствующих/неправильных данных.

Вот определение таблицы:

oid oid[] NOT NULL,
"State" character varying(2)[] NOT NULL,
release_1121 numeric NOT NULL,
release_1122 numeric NOT NULL,
CONSTRAINT oid PRIMARY KEY (oid)

Я хотел бы добавить столбец процентного увеличения и заполнить его правильными процентами.


person justanother1    schedule 10.05.2012    source источник
comment
1121, 1122 — это имена полей или значения? Пожалуйста, опубликуйте здесь полное определение таблицы. И покажите нам, что вы сделали до сих пор.   -  person vyegorov    schedule 10.05.2012
comment
Похоже, должна быть таблица release с одной суммой для каждого выпуска и представлением/функцией, вычисляющей изменение между всеми/выбранными выпусками. Не таблица разницы между выпусками. Также, пожалуйста, укажите вашу версию Postgres и предполагаемую цель расчета (чтобы лучше понять, что вам нужно).   -  person Erwin Brandstetter    schedule 10.05.2012


Ответы (2)


Я бы сказал, что добавление столбца процентного увеличения - это одноразовая операция, которую можно выполнить следующим образом (подробности в документации):

ALTER TABLE target ADD pct float;

И тогда вы можете обновить таблицу, заполнив ее новыми значениями:

UPDATE target SET pct = (after::float - before::float) / before::float;
person vyegorov    schedule 10.05.2012

Я думаю, что вам действительно нужно:

Таблица должна выглядеть примерно так:

CREATE TABLE release (
release_id integer PRIMARY KEY,    -- pk is NOT NULL automatically
-- state varchar(2)[] NOT NULL,    -- ??
amount numeric NOT NULL
);

Данные испытаний:

INSERT INTO release VALUES (release_id, amount)
  (1121, 25)
, (1122, 30)
, (1123, 90)
, (1124, 10);

Запрос:

WITH x AS (
    SELECT *
         , lag(amount) OVER (ORDER BY release_id) as last_amount
    FROM   release
    )
SELECT release_id, amount
     , (amount - last_amount) AS abs_change
     , round((100 * (amount - last_amount)) / last_amount, 2) AS percent_change
FROM   x
ORDER  BY release_id;

CTE (предложение WITH) и оконная функция lag() требуется PostgreSQL 8.4 или более поздней версии.
Результат:

release_id | amount | abs_change | percent_change
-----------+--------+------------+---------------
1121       | 25     | <NULL>     | <NULL>
1122       | 30     | 5          |  20.00
1123       | 90     | 60         | 200.00
1124       | 10     | -80        | -88.89
person Erwin Brandstetter    schedule 10.05.2012
comment
Это как раз именно то, что я думал предложить, прежде чем я получил ваш ответ! Нет избыточного хранения сумм, поэтому, если одна сумма оказывается неправильной, вы исправляете эту одну сумму, и все готово; нет необходимости искать избыточные копии или пересчитывать зависимые значения. - person kgrittn; 10.05.2012
comment
@kgrittn: Та же идея, вероятно, потому, что это очевидный способ избежать избыточного хранилища. :) - person Erwin Brandstetter; 11.05.2012