Платёжный документ

Имеется таблица в данными по платежным документам. Необходимо написать запрос, который выведет все документы того типа, которого за все время было по сумме больше всего. Если таких типов несколько, то вывести все такие типы. Для каждой строки результата вывести промежуточную сумму платежей данного типа от самого раннего до текущего платежа включительно.

Структура таблицы:

CREATE TABLE "PAYMENT_DOCUMENT" 
("ID" INTEGER,
 "PAY_TYPE" INTEGER,
 "PAY_DATE" DATE,
 "PAY_SUM" NUMBER
) TABLESPACE MIRAVILD_DATA;
 
COMMENT ON TABLE "PAYMENT_DOCUMENT" IS 'Платёжный документ';
COMMENT ON COLUMN "PAYMENT_DOCUMENT"."ID" IS 'Идентификатор платёжного документа';
COMMENT ON COLUMN "PAYMENT_DOCUMENT"."PAY_TYPE" IS 'Тип платёжного документа';
COMMENT ON COLUMN "PAYMENT_DOCUMENT"."PAY_DATE" IS 'Дата платежа';
COMMENT ON COLUMN "PAYMENT_DOCUMENT"."PAY_SUM" IS 'Сумма платежа';

CREATE UNIQUE INDEX "U_IDX_PAYMENT_DOCUMENT" ON "PAYMENT_DOCUMENT" ("ID") TABLESPACE MIRAVILD_INDEX;

ALTER TABLE "PAYMENT_DOCUMENT" ADD CONSTRAINT "PK_PAYMENT_DOCUMENT" PRIMARY KEY ("ID") 
USING INDEX "U_IDX_PAYMENT_DOCUMENT" ENABLE VALIDATE;
/

Пример данных:

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (1, 1, to_date('01.01.2012', 'dd.mm.yyyy'), 100);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (2, 1, to_date('02.01.2012', 'dd.mm.yyyy'), 200);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (3, 1, to_date('03.01.2012', 'dd.mm.yyyy'), 300);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (4, 1, to_date('01.02.2012', 'dd.mm.yyyy'), 400);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (5, 1, to_date('01.02.2012', 'dd.mm.yyyy'), 500);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (6, 2, to_date('01.01.2012', 'dd.mm.yyyy'), 600);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (7, 2, to_date('01.02.2012', 'dd.mm.yyyy'), 700);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (8, 2, to_date('01.04.2012', 'dd.mm.yyyy'), 800);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (9, 2, to_date('01.05.2012', 'dd.mm.yyyy'), 900);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (10, 2, to_date('01.06.2012', 'dd.mm.yyyy'), 1000);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (11, 3, to_date('10.01.2012', 'dd.mm.yyyy'), 1100);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (12, 3, to_date('01.03.2012', 'dd.mm.yyyy'), 1200);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (13, 3, to_date('01.05.2012', 'dd.mm.yyyy'), 1300);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (14, 3, to_date('05.05.2012', 'dd.mm.yyyy'), 1400);

INSERT INTO payment_document
  (id, pay_type, pay_date, pay_sum)
VALUES
  (15, 3, to_date('01.06.2012', 'dd.mm.yyyy'), 1500);

COMMIT WORK;
/

Варианты запроса:

SELECT pd.*,
       SUM(pd.pay_sum) over(PARTITION BY pd.pay_type ORDER BY pd.pay_date ASC) as SM
  FROM payment_document pd
  JOIN (SELECT pd.pay_type
          FROM (SELECT pd.pay_type,
                       SUM(pd.pay_sum) AS sm,
                       MAX(SUM(pd.pay_sum)) over() AS maxsm
                  FROM payment_document pd
                 GROUP BY pd.pay_type) pd
         WHERE pd.sm = pd.maxsm) t
    ON t.pay_type = pd.pay_type;
/

SELECT pd.*,
       SUM(pd.pay_sum) over(PARTITION BY pd.pay_type ORDER BY pd.pay_date ASC) as SM
  FROM payment_document pd
  JOIN (SELECT pd.pay_type
          FROM (SELECT pd.pay_type,
                       SUM(pd.pay_sum) AS sm,
                       rank() over(ORDER BY SUM(pd.pay_sum) DESC) AS rn
                  FROM payment_document pd
                 GROUP BY pd.pay_type) pd
         WHERE pd.rn = 1) t
    ON t.pay_type = pd.pay_type;
/

Результат:

ID	PAY_TYPE	PAY_DATE	PAY_SUM	SM
11	3		10.01.2012	1100		1100
12	3		01.03.2012	1200		2300
13	3		01.05.2012	1300		3600
14	3		05.05.2012	1400		5000
15	3		01.06.2012	1500		6500

P.S.
Конфигурация СУБД — Oracle Database 11g Express Edition Release 11.2.0.2.0
IDE — PL/SQL Developer Version 11.0.6.1776

Tags: ,

Comments are closed.