2014-10-13 6 views
0

Я искал «текущие итоги» для SQL Server. Легкий запрос. Итак, я написал следующее:SQL Server работает итоговые суммы (сумма по заказу)

SELECT 
    firstname, lastname, thetot, 
    SUM(thetot) OVER (ORDER BY lastname) AS runningtot 
FROM 
    customers 

Вы считаете, что точный общий итог будет выходом. Не обязательно верно. Вот что он выплюнул:

firstname lastname thetot runningtot 

Billy  BobThornton 0.01 4.46 
Billy  BobThornton 4.45 4.46 
Bob   Hope  3.52 7.98 
Jimmy  Johnson  4.84 12.82 
Jason  Meyers  3.50 16.32 
Ted   Turner  1.77 18.09 

Является ли это только мне или если первая запись бежит быть 0.01?

+0

Вам нужно какое-то дополнительное поле для заказа, например дата или уникальный идентификатор, представляющий порядок ввода. – Namrehs

+0

Это может быть вызвано тем, что столбец, который вы сортируете, не уникален. Попробуйте добавить другой (возможно уникальный) столбец в 'order by' для разрыва связей. –

+0

Btw: Postgres и Oracle ведут себя точно так же. –

ответ

0

Самостоятельный ответ, который вы предоставили, существенно изменяет семантику.

В вопросе вы вычисляете общее количество, как было заказано по первому имени, произвольно переключаясь на порядок с помощью ПК, возвращает результат, который отвечает на совершенно другой вопрос.

Причина результирующем, что вы видите документирован in books online

Если РЯДЫ/RANGE не указано, но указано ORDER BY, RANGE неограничена ПРЕДЫДУЩИЙ И CURRENT ROW используется по умолчанию для окна кадра ,

Семантика RANGE является то, что значения связаны с одной и той же ORDER BY значения всегда будут включены в друг друга оконной рамы.

Один из способов, который совместим с исходной семантикой, заключается в том, чтобы добавить выключатель связи к ORDER BY, который обеспечивает уникальность - и, следовательно, связи никогда не могут произойти.

SELECT firstname, 
     lastname, 
     thetot, 
     SUM(thetot) OVER (ORDER BY lastname, pk) AS runningtot 
FROM customers 

Однако это не лучший метод исполнительский.

Как обсуждалось в Aaron Bertrand's running total comparison осуществление RANGE менее хорошо выполнения, чем для ROWS.

Кроме того, ROWS ведет себя так, как вы ожидали.

SELECT firstname, 
     lastname, 
     thetot, 
     SUM(thetot) OVER (ORDER BY lastname ROWS UNBOUNDED PRECEDING) AS runningtot 
FROM customers 

вернуть бы

| firstname | lastname | thetot | runningtot | 
|-----------|-------------|--------|------------| 
|  Billy | BobThornton | 0.01 |  0.01 | 
|  Billy | BobThornton | 4.45 |  4.46 | 
|  Bob |  Hope | 3.52 |  7.98 | 
|  Jimmy |  Johnson | 4.84 |  12.82 | 
|  Jason |  Meyers | 3.5 |  16.32 | 
|  Ted |  Turner | 1.77 |  18.09 | 

Или, возможно,

| firstname | lastname | thetot | runningtot | 
|-----------|-------------|--------|------------| 
|  Billy | BobThornton | 4.45 |  4.45 | 
|  Billy | BobThornton | 0.01 |  4.46 | 
|  Bob |  Hope | 3.52 |  7.98 | 
|  Jimmy |  Johnson | 4.84 |  12.82 | 
|  Jason |  Meyers | 3.5 |  16.32 | 
|  Ted |  Turner | 1.77 |  18.09 | 

в любом случае (это undeterministic, какая строка будет отображаться первым в присутствии связей)

Смежные вопросы