2015-11-02 6 views
0

У меня есть бюджет таблицы, как это:Вычислить сумму бюджета

╔════╦══════╦═══════╦═══════════╦══════╗ 
║ Id ║ Site ║ Rayon ║ Date ║ Amt ║ 
╠════╬══════╬═══════╬═══════════╬══════╣ 
║ 1 ║ 20 ║ 23 ║ 2015-11-3 ║ 200 ║ 
║ 2 ║ 40 ║  2 ║ 2015-12-4 ║ 20 ║ 
║ 3 ║ 20 ║  3 ║ 2015-11-4 ║ 400 ║ 
║ 4 ║ 30 ║ 13 ║ 2015-11-5 ║ 500 ║ 
║ 5 ║ 20 ║ 23 ║ 2015-08-3 ║ 200 ║ 
╚════╩══════╩═══════╩═══════════╩══════╝ 

Как рассчитать сумму АМТ с сегодняшнего дня до конца месяца, а с сегодняшнего дня до конца года?

+2

Пробовали ли вы что-нибудь? Посмотрите на Group By и Datepart. –

+0

, какую версию сервера sql вы используете? – pedram

+0

@rajeshmpanchal sql server 2008 – user3548593

ответ

2

С такой проблемой, как это, первое, что вам нужно сделать, это понять, как вычислить " конец этого месяца »и« конец этого года ». Используя sql2008, у вас нет доступа к полезной функции EOMONTH(), поэтому вы должны рассчитать это самостоятельно.

Есть a few different ways of doing this, но я пошел за тем, который рассчитает несколько миллисекунд до полуночи в последний день текущего месяца и в последний день текущего года.

declare @date DATETIME = getdate() 

select dateadd(millisecond,-3,DATEADD(MONTH,datediff(MONTH,0,@date)+1,0)) as EOMONTH 
select dateadd(millisecond,-3,DATEADD(year,datediff(year,0,@date)+1,0)) as EOYEAR 

(. Примечание: -3 связанно с типом dattime данных SQL-сервером, имеющим minimum accuracy of 3ms поэтому принимать 3 мс с начала следующего месяца/следующий годом настолько точно, как вы собираетесь получить в любом дело это имеет очень мало все, что мы пытаемся сделать, это получить дату границы как можно ближе к концу месяца/конец года, как это возможно)


Учитывая этот бит работал, вы могли бы использовать их по отдельности в двух разных запросах

DECLARE @now DATETIME = GETDATE(); 
DECLARE @eomonth DATETIME = dateadd(millisecond,-3,DATEADD(MONTH,datediff(MONTH,0,@date)+1,0)) 
DECLARE @eoyear DATETIME = dateadd(millisecond,-3,DATEADD(year,datediff(year,0,@date)+1,0)) 

SELECT SUM(amt) FROM Budget 
WHERE date >= @now AND date <[email protected] 

SELECT SUM(amt) FROM Budget 
WHERE date >= @now AND date <= @eoyear 

Или, вы можете объединить их

SELECT SUM(CASE WHEN DATE<@eomonth THEN Amt ELSE 0 END) AS summonth, 
     SUM(CASE WHEN DATE<@eoyear THEN Amt ELSE 0 END) AS sumyear 
FROM Budget 
WHERE Date>[email protected] 
+1

Мне не нравятся все эти манипуляции с миллисекундами. Это становится не просто, что вы делаете. –

+0

Что не так просто? Возьмите [минимальную точность - 3 мс] с начала следующего месяца/следующего года.Это примерно так же просто, как вы можете получить в SQL2008 – Jamiec

+1

Для новичков трудно понять, почему 3 миллисекунды? Почему не 5 или 47 миллисекунд? –

1

Для конца текущего месяца:

SELECT SUM(Amt) AS Amt 
FROM TableName 
WHERE Date >= CAST(GETDATE() AS DATE) AND 
     Date < DATEADD(m, 1, DATEADD(dd, -DAY(GETDATE()) + 1, CAST(GETDATE() AS DATE))) 

Для конца текущего года:

SELECT SUM(Amt) AS Amt 
FROM TableName 
WHERE Date >= CAST(GETDATE() AS DATE) AND 
     Date < CAST(YEAR(GETDATE()) + 1 AS char(4)) + '0101' 
0

К сожалению, ваш SQL версия старее для поддержки функции системы под названием EOMONTH

Эта простая функция будет эквивалентна для EOMONTH. Эта функция будет очень полезна при сложном вычислении даты, уменьшив длину запроса.

CREATE FUNCTION dbo.endofmonth(@date DATETIME= NULL) 
RETURNS DATETIME 
BEGIN 
RETURN DATEADD(DD, -1, DATEADD(MM, +1, DATEADD(DD, 1 - DATEPART(DD, ISNULL(@date,GETDATE())), ISNULL(@date,GETDATE())))) 
END 

Запрос на выполнение работ:

SELECT dbo.endofmonth(DEFAULT) --Current month-end date 
SELECT dbo.endofmonth('02/25/2012') --User-defined month-end date 

Ваша ситуация

/**** To get end of current month ****/ 

SELECT SUM([amt]) FROM budget WHERE [date] >= getdate() AND [date] <= CONVERT(DATE,dbo.endofmonth(DEFAULT)) 

/**** To get end of current year ****/ 
SELECT SUM([amt]) FROM budget WHERE [date] >= getdate() AND [date] <= CONVERT(DATE,DATEADD(yy, DATEDIFF(yy,0,getdate()) + 1, -1))