Обработка месяца и суммы в SQL Server 2008 - PullRequest
1 голос
/ 15 ноября 2011

У меня есть таблица с 3 столбцами: ID, AmountCollected, Date.Мне нужно создать хранимую процедуру, которая возвращает мне данные, подобные этой.

Month--CollectionSum
Jan2011|500
Feb2011|549
Mar2011|678
............

Сумма сбора за январь 2011 года должна быть суммой AmountCollected с датами января 2011 года или раньше, аналогично сумма сбора за февраль 2011 года должна быть суммойAmountCollected с датами февраля 2011 года или раньше и так далее ...

Можете ли вы помочь мне в этом?Мне нужно построить запрос на SQL Server 2008.

Ответы [ 3 ]

1 голос
/ 15 ноября 2011
WITH T AS (
    SELECT SUM(AmountCollected) AS SubTotal, YEAR([Date]) AS Y, MONTH([Date]) AS M,
    ROW_NUMBER() OVER (ORDER BY YEAR([Date]), MONTH([Date])) AS OrderID 
    FROM TestTable
    GROUP BY YEAR([Date]), MONTH([Date]) 
)
SELECT Y, M, SubTotal, 
 (SELECT SUM(T.SubTotal) FROM T WHERE OrderID <= A.OrderID) AS RunningTotal
FROM T AS A
ORDER BY Y, M

Вот еще одна версия без использования подзапроса, которая должна сделать его быстрее:

WITH T AS (
    SELECT SUM(AmountCollected) AS SubTotal, YEAR([Date]) AS Y, MONTH([Date]) AS M,
    ROW_NUMBER() OVER (ORDER BY YEAR([Date]), MONTH([Date])) AS OrderID 
    FROM TestTable
    GROUP BY YEAR([Date]), MONTH([Date]) 
)
SELECT A.Y, A.M, A.SubTotal, A.SubTotal + ISNULL(B.SubTotal, 0) AS RunningTotal
FROM T AS A
LEFT JOIN T AS B ON A.OrderID = B.OrderID + 1
ORDER BY A.Y, A.M

Поле RunninigTotal добавляет текущую строку SubTotal с предыдущей строкой SubTotal. Не используя другую SUM для вычисления RunningTotal, вы повышаете скорость, избегая добавления каждой строки к значениям всех предыдущих строк.

0 голосов
/ 15 ноября 2011

Сначала создайте таблицу регулярных месячных сумм.Соедините два экземпляра этой таблицы с условиями для сопоставления каждой строки первой таблицы со строками из другой таблицы, содержащей сумму за этот и все предыдущие месяцы.Наконец группа по месяцам.

with SumTbl (YrMon, SumAmt) as
(
   select Year(dte)*100+Month(dte), sum(amount)
   from Tbl
   group by Year(dte)*100+Month(dte)
)
select t1.YrMon, sum (t2.SumAmt) as CumAmt
from SumTb1 t1, SumTbl t2
where t2.YrMon <= t1.YrMon
group by t1.YrMon
order by t1.YrMon;
0 голосов
/ 15 ноября 2011

Вот пример, который вы можете изменить в соответствии со своими потребностями:

http://www.sqlservercentral.com/Forums/Topic460765-338-1.aspx

Ключом к промежуточной сумме является создание оператора, который объединяет таблицу с выражением, которое группируетсяДата.Но вместо того, чтобы сказать table.date = groupeddata.date, вы говорите table.date <= groupeddata.date, чтобы выбрать не только текущую, но и все предыдущие даты.Во всяком случае, это будет иметь больше смысла, когда вы прочитаете ответ в ссылке. </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...