Год до даты в месяц - PullRequest
       0

Год до даты в месяц

4 голосов
/ 25 февраля 2010

У меня есть эта таблица под названием Sales:

ID Date       DepartmentID Amount
1  10-12-2009           12     10
2  18-01-2010            3     23 
3  08-02-2010            4      7
...

Теперь мне нужно получить значения YTD из столбца Сумма для каждого месяца и отдела.

Сначала я попробовал этот запрос:

SELECT MonthSales.[Month], MonthSales.DepartmentID,

    (SELECT SUM(SalesAmount.Amount) FROM Sales AS SalesAmount
        WHERE (SalesAmount.[Date] >= DATEADD(Month, -12, MonthSales.[Month]) 
            AND SalesAmount.[Date] < DATEADD(Month, 1, MonthSales.[Month]))
        AND SalesAmount.DepartmentID = MonthSales.DepartmentID) AS Amount

FROM (SELECT dateadd(month, datediff(month, 0, [Date]),0) AS [Month], DepartmentID
    FROM Sales) AS MonthSales
GROUP BY MonthSales.[Month], MonthSales.DepartmentID

Но это вернулось Внутренняя ошибка SQL Server

Чтобы обойти эту ошибку, я написал следующий запрос:

SELECT CompareSales.StartDate, CompareSales.EndDate, CompareSales.DepartmentID,

    (SELECT SUM(SalesAmount.Amount) FROM Sales AS SalesAmount
        WHERE (SalesAmount.[Date] >= CompareSales.StartDate AND SalesAmount.[Date] < 
            DATEADD(Month, 1, CompareSales.EndDate))
        AND SalesAmount.DepartmentID = CompareSales.DepartmentID) AS Amount

FROM (SELECT DATEADD(Month, -12, PeriodSales.EndDate) AS StartDate,    
    PeriodSales.EndDate, PeriodSales.DepartmentID
    FROM (SELECT DISTINCT bms.DATESERIAL(DATEPART(Year, EndSales.[Date]), DATEPART 
        (Month, EndSales.[Date]), 1) AS EndDate, EndSales.DepartmentID
        FROM Sales AS EndSales) AS PeriodSales) AS CompareSales

GROUP BY CompareSales.StartDate, CompareSales.EndDate, CompareSales.DepartmentID
ORDER BY CompareSales.StartDate

Этот запрос возвращал правильные суммы за год для каждого месяца, но для обработки всех 4800 записей потребовалось 6 минут. Это слишком медленно, конечно. Может ли кто-нибудь помочь мне в направлении запроса, который вернет суммы с начала года в течение приемлемого времени (<30 секунд)? </p>

Спасибо

Bob

1 Ответ

2 голосов
/ 25 февраля 2010

попробуйте это:

DECLARE @YourTable table (RowID int, DateOf datetime, DepartmentID int, Amount int)

INSERT INTO @YourTable VALUES (1,'12-10-2009',12,10) --changed dd-mm-yyyy to mm-dd-yyyy so it would work on my system
INSERT INTO @YourTable VALUES (2,'01-18-2010', 3,23)
INSERT INTO @YourTable VALUES (3,'02-08-2010', 4, 7)

SELECT
    DATEPART(mm,DateOf) AS MonthOf,DepartmentID,SUM(Amount) AS TotalAmount
    FROM @YourTable
    WHERE DateOf>='01-01-2010' AND DateOF<'01-01-2011'
    GROUP BY DATEPART(mm,DateOf),DepartmentID

ВЫХОД

MonthOf     DepartmentID TotalAmount
----------- ------------ -----------
1           3            23
2           4            7

(2 row(s) affected)

если вам все еще нужна большая скорость, создайте вычисляемый столбец PERSISTED: MonthOfDate, который является DATEPART (mm, DateOf), и добавьте к нему индекс:

ALTER TABLE YourTable ADD MonthOfDate AS DATEPART(mm,DateOf) PERSISTED 

CREATE NONCLUSTERED INDEX IX_YourTable_MonthOfDate 
ON YourTable (MonthOfDate)

или даже:

CREATE NONCLUSTERED INDEX IX_YourTable_MonthOfDate 
ON YourTable (DateOf,MonthOfDate)

если вам не нужен вычисляемый столбец PERSISTED, создайте индексированное представление.

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