MariaDB работает до N и строк, не включенных в его расчет - PullRequest
0 голосов
/ 18 апреля 2020

У меня есть таблица, в которой среди других столбцов есть amt и created (отметка времени).

  1. Я пытаюсь вычислить промежуточный итог от amt до N
  2. Получить все строки, не включенные в вычисление, ведущие к сумме до N

Я делаю это в коде, но мне было интересно, есть ли способ получить это с SQL и в идеале в одном запросе.

Оглядываясь вокруг, можно легко найти примеры вычисления промежуточного итога, например { ссылка }, но не так, чтобы найти промежуточный итог N а затем только фактически возвращают строки, не участвующие в вычислении N.

1 Ответ

1 голос
/ 18 апреля 2020

Вы можете использовать оконную версию агрегатной функции SUM, чтобы получить промежуточную сумму для каждой строки.

CREATE TABLE TEST (ID BIGINT PRIMARY KEY, AMT INT, CREATED TIMESTAMP);

INSERT INTO TEST VALUES
(1, 1, TIMESTAMP '2000-01-01 00:00:00'),
(2, 2, TIMESTAMP '2000-01-02 00:00:00'),
(3, 1, TIMESTAMP '2000-01-03 00:00:00'),
(4, 3, TIMESTAMP '2000-01-04 00:00:00'),
(5, 5, TIMESTAMP '2000-01-05 00:00:00'),
(6, 1, TIMESTAMP '2000-01-07 00:00:00');

SELECT ID, AMT, SUM(AMT) OVER (ORDER BY CREATED) RT, CREATED FROM TEST ORDER BY CREATED;

> ID AMT RT CREATED
> -- --- -- -------------------
> 1  1   1  2000-01-01 00:00:00
> 2  2   3  2000-01-02 00:00:00
> 3  1   4  2000-01-03 00:00:00
> 4  3   7  2000-01-04 00:00:00
> 5  5   12 2000-01-05 00:00:00
> 6  1   13 2000-01-07 00:00:00

Затем вы можете использовать нестандартное предложение QUALIFY в H2 или подзапрос (как в MariaDB, так и в H2), чтобы отфильтровать строки ниже предела.

Если N является пределом промежуточного итога, а под «строками, не включенными в расчет», вы подразумеваете строки выше лимита, запросы будет выглядеть следующим образом:

-- Simple non-standard query for H2
SELECT ID, AMT, SUM(AMT) OVER (ORDER BY CREATED) RT, CREATED FROM TEST
    QUALIFY RT > 10 ORDER BY CREATED;
-- Equivalent standard query with subquery for MariaDB, H2, and many others
SELECT * FROM (
    SELECT ID, AMT, SUM(AMT) OVER (ORDER BY CREATED) RT, CREATED FROM TEST
) T WHERE RT > 10 ORDER BY CREATED;

> ID AMT RT CREATED
> -- --- -- -------------------
> 5  5   12 2000-01-05 00:00:00
> 6  1   13 2000-01-07 00:00:00

RT - AMT в первом ряду приведен промежуточный итог всех предыдущих рядов. Вы можете выбрать его отдельно, если вы sh:

-- Non-standard query for H2
SELECT SUM(AMT) OVER (ORDER BY CREATED) RT FROM TEST
    QUALIFY RT < 10 ORDER BY CREATED DESC FETCH FIRST ROW ONLY;
-- Non-standard query for MariaDB or H2
SELECT RT FROM (
    SELECT ID, AMT, SUM(AMT) OVER (ORDER BY CREATED) RT, CREATED FROM TEST
) T WHERE RT < 10 ORDER BY CREATED DESC LIMIT 1;
-- Standard query for H2 and others (but not for MariaDB)
SELECT RT FROM (
    SELECT ID, AMT, SUM(AMT) OVER (ORDER BY CREATED) RT, CREATED FROM TEST
) T WHERE RT < 10 ORDER BY CREATED DESC FETCH FIRST ROW ONLY;

> RT
> --
> 7

Если вы имели в виду что-то другое, критерии QUALIFY или WHERE будут другими.

...