Отправляет email-рассылки с помощью сервиса Sendsay

Вопросы и ответы по MS SQL Server

  Все выпуски  

Вопросы и ответы по MS SQL Server - Выпуск No. 33


Информационный Канал Subscribe.Ru


Вопросы и ответы по MS SQL Server

Выпуск No. 33 от 2004-04-23

Слова

Если Вы не можете найти ответ на свой вопрос среди тех ответов и вопросов, которые дал я. Или если Вам надо срочно решить свою проблему относительно MS SQL Server, то добро пожаловать на форум сайта sql.ru. Самый лучший, быстрый и популярный сайт, на котором можно быстро получить достаточно профессиональный ответ.
Вопрос : Как в возвращаемом наборе данных сформировать столбец B, в котором каждая строчка будет содержать сумму всех предыдущих по столбцу А?

Ответ:
Создадим и заполним таблицу, с которой будем работать. Пусть это будет таблица продаж:
CREATE TABLE Sales

(
SaleID int IDENTITY PRIMARY KEY CLUSTERED,
ClientID int,
Date datetime,
Amount money
)
GO
insert Sales values(1,'20030301', 15.48)
insert Sales values(1,'20030302', 134.01)
insert Sales values(1,'20030303', 2346.03)
insert Sales values(2,'20030303', 754.88)
insert Sales values(3,'20030301', 73.07)
insert Sales values(3,'20030302', 734.46)
insert Sales values(4,'20030301', 10)
insert Sales values(4,'20030304', 20)
insert Sales values(4,'20030307', 30)
insert Sales values(4,'20030309', 40)
insert Sales values(5,'20030301', 1975.73)
insert Sales values(5,'20030306', 178965.63)
GO

В ней содержатся данные по различным клиентам по датам. Результатом нам надо получить таблицу, в которой будет дополнительная колонка, содержащая нарастающую сумму продаж для каждого клиента:
SaleID ClientID Date            Amount       Total

1 1 2003-03-01 15.4800 15.4800
2 1 2003-03-02 134.0100 149.4900
3 1 2003-03-03 2346.0300 2495.5200
4 2 2003-03-03 754.8800 754.8800
5 3 2003-03-01 73.0700 73.0700
6 3 2003-03-02 734.4600 807.5300
7 4 2003-03-01 10.0000 10.0000
8 4 2003-03-04 20.0000 30.0000
9 4 2003-03-07 30.0000 60.0000
10 4 2003-03-09 40.0000 100.0000
11 5 2003-03-01 1975.7300 1975.7300
12 5 2003-03-06 178965.6300 180941.3600

Если Вам не надо постоянно хранить колонку нарастающего итога Total и объем данных небольшой, то вполне подойдет следующий запрос:
select a.SaleID, a.ClientID, a.Date, a.Amount, sum(b.Amount) as Total

from Sales a
join Sales b on b.ClientID = a.ClientID and b.SaleID <= a.SaleID
group by a.SaleID, a.ClientID, a.Date, a.Amount
order by a.SaleID

Как вариант этого запроса можно привести следующий код:
select a.SaleID, a.ClientID, a.Date, a.Amount,

(select sum(b.Amount)
from Sales b
where b.ClientID = a.ClientID and b.SaleID <= a.SaleID
) as Total
from Sales a
order by a.SaleID

Выбор варианта остается за Вами.

В случае же если объем данных большой или Вам надо постоянно хранить колонку Total, то лучше использовать особенности оператора UPDATE:
declare @Total money, @ClientID int

set @Total = 0
set @ClientID = 0

select *, cast(0 as money) as Total into #temp from Sales


update #temp set
@Total = Total =
case
when ClientID = @ClientID then @Total
else 0
end + Amount,
@ClientID = ClientID

select * from #temp
drop table #temp


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

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

Не забудьте удалить экспериментальную таблицу Sales:
DROP TABLE Sales


Надеюсь, Вы нашли эту информацию полезной. Вопросы, предложения и пожелания шлите на адрес sql@softmatics.ru
С уважением, Сергей Кошкин, ведущий специалист ООО "Софтоматика"
Список всех вопросов и ответов по MS SQL Вы найдете на сайте Рассылки http://sql.softmatics.ru/ или http://sql.ru/users/sergcat/
SM Plasma LITE - программа для автоматизации склада, бухгалтерии, торговли. Анализ, прогноз, CRM и многое другое по цене $0.00!
Рейтинг@Mail.ru

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу


В избранное