Найти сумму столбцов в зависимости от текущего месяца в SQL Server 2005 - PullRequest
2 голосов
/ 11 августа 2011

У меня есть следующая таблица. В каждой строке хранится ряд значений в указанных столбцах.

create table MonthlyData (
 Jan int not null,
 Feb int not null,
 Mar int not null,
 Apr int not null,
 May int not null,
 Jun int not null,
 Jul int not null,
 Aug int not null,
 Sep int not null,
 Oct int not null,
 Nov int not null,
 Dec int not null
)

insert into table (3, 1, 3, 4, 5, 6, 7, 8, 9, 4, 3, 2)
.
.
.

Что я хочу сделать, так это в зависимости от месяца года для каждой строки суммировать значения от первого столбца (январь) до столбца, представляющего текущий месяц (например, август), включая столбец. Я подозреваю, что это, вероятно, будет включать в себя какую-то функцию, которая принимает месяц в качестве параметра. Конечно, будут тысячи строк, и не каждый ряд будет уникальным.

Я не совсем уверен, с чего начать или какие встроенные функции / ключевые слова sql использовать для этого. Кто-нибудь сможет указать мне правильное направление?

UPDATE:

Основываясь на решении Андрея М, я придумал это.

declare @currentMonth int
set @currentMonth = 8
select sum(p1*Jan+p2*Feb+p3*Mar+p4*Apr+
  p5*May+p6*Jun+p7*Jul+p8*Aug+
  p9*Sep+p10*Oct+p11*Nov+p12*Dec) as 'Balance'
from MonthlyData md
cross join MatrixTable mt
where mt.period = @currentMonth

Таблица матриц представляет собой единичную матрицу с нижней левой половиной, заполненной цифрами 1 вместо 0 (имена столбцов начинаются с произвольного префикса, в данном случае «p», за которым следует число). В конце добавляется дополнительный столбец для идентификации каждой строки. Таблица матрицы будет полезна и для других задач в будущем, если она достаточно велика.

Ответы [ 3 ]

3 голосов
/ 11 августа 2011

Если изменение, предложенное в моем другом ответе, слишком радикально, чтобы принять его, то вот альтернатива решению @Filip De Vos:

SELECT
  SUM(
    CASE v.number
      WHEN  1 THEN Jan
      WHEN  2 THEN Feb
      WHEN  3 THEN Mar
      WHEN  4 THEN Apr
      WHEN  5 THEN May
      WHEN  6 THEN Jun
      WHEN  7 THEN Jul
      WHEN  8 THEN Aug
      WHEN  9 THEN Sep
      WHEN 10 THEN Oct
      WHEN 11 THEN Nov
      WHEN 12 THEN Dec
    END
  ) AS Total
FROM MonthlyData m
  CROSS JOIN master..spt_values v
WHERE v.type = 'P'
  AND v.number BETWEEN 1 AND MONTH(GETDATE())

Таблица master..spt_values являетсяСистемная таблица используется для внутренних целей, но также может использоваться в пользовательских запросах.Одно из его подмножеств содержит список целых чисел от 0 до 2047, который во многих случаях можно использовать в качестве готовой таблицы подсчета .

2 голосов
/ 11 августа 2011

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

CREATE TABLE MonthlyData (
  Month int,
  Value int
)

, где Month будет содержать значения от 1 до 12. Тогда суммирование данных будет очень простым:

SELECT
  SUM(Value) AS Total
FROM MonthlyData
WHERE Month BETWEEN 1 AND MONTH(GETDATE())
2 голосов
/ 11 августа 2011

Вы можете использовать оператор case, чтобы установить нулевые данные, которые вы не хотите.

declare @current_month int
select @current_month = month(current_timestamp)

select case when @current_month <= 1 then jan else 0 end 
     + case when @current_month <= 2 then feb else 0 end 
     + case when @current_month <= 3 then mar else 0 end 
     + case when @current_month <= 4 then apr else 0 end 
     + case when @current_month <= 5 then may else 0 end 
     + case when @current_month <= 6 then jun else 0 end 
     + case when @current_month <= 7 then jul else 0 end 
     + case when @current_month <= 8 then aug else 0 end 
     + case when @current_month <= 9 then sep else 0 end 
     + case when @current_month <= 10 then oct else 0 end 
     + case when @current_month <= 11 then nov else 0 end 
     + case when @current_month <= 12 then dec else 0 end 
from MonthlyData
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...