Странно вычислять данные на столе

У меня есть такой стол

Table1(A,B)

A    B
3    0
4    3
2    2
0    1
3    5
4    6
.    .
.    .
.    .
.    .

В нем около 3 миллионов строк. Я хочу рассчитать это:

A_SUM = 3 * (3 + 2 + 1 + 5 + 6 +.......) + 4 * (2 + 1 + 5 + 6 +........) + 2 * (1+ 5 + 6 +...) + 0 * (5 + 6 +...) + 3 * (6 +...) +........

B_SUM = 0 * (4 + 2 + 0 + 3 + 4 +.......) + 3 * (2 + 0 + 3 + 4 +........) + 2 * (0+ 3 + 4 +...) + 1 * (3 + 4 +...) + 5 * (4 +...) +............

Как я могу рассчитать эти данные?

1 ответ

Решение

Вы можете делать что хотите с накопленной суммой. Следующий синтаксис является стандартом ANSI и должен работать (в зависимости от версии вашей базы данных):

select sum(a*(revcumb - b)) as a_sum, sum(b*(revcuma - a)) as b_sum
from (select t.*,
             sum(b) over (order by id desc) as revcumb,
             sum(a) over (order by id desc) as revcuma
      from table t
     ) t;

Обратите внимание, что вместо использования rows between или же range between, это просто вычитает значение в текущей строке из (обратной) совокупной суммы.

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

И, если у вас нет накопленной суммы (т. Е. SQL Server < 2012), то вы можете сделать то же самое с коррелированными подзапросами.

РЕДАКТИРОВАТЬ:

Sybase может или не может поддерживать вышеизложенное. Существует так много разных версий этой базы данных, что вряд ли она стоит как тег. Я думаю, что это будет работать на большинстве версий:

select sum(a*revcumb) as a_sum, sum(b*revcuma) as b_sum
from (select t.*,
             (select sum(b) from table t2 where t2.id > t.id) as revcumb,
             (select sum(a) from table t2 where t2.id > t.id) as revcuma
      from table t
     ) t;
Другие вопросы по тегам