2012-03-12 92 views
0

我有以下存儲過程:GROUP BY日期範圍?

SELECT tsks.grouping_ref, ttg.description AS grouping_desc, 
SUM(ts.booked_time) AS booked_time_total, 
DATENAME(MONTH, ts.start_dtm) + ' ' + DATENAME(YEAR, ts.start_dtm) AS month_name, 
@month_ref AS month_ref 

FROM timesheets ts 
JOIN timesheet_categories cat 
ON ts.timesheet_cat_ref = cat.timesheet_cat_ref 

JOIN timesheet_tasks tsks 
ON ts.task_ref = tsks.task_ref 

JOIN timesheet_task_groupings ttg 
ON tsks.grouping_ref = ttg.grouping_ref 

WHERE ts.status IN(1, 2) --Booked and approved 
AND cat.is_leave_category = 0 --Ignore leave 
--AND DATEPART(YEAR, ts.start_dtm) = @Year 
--AND DATEPART(MONTH, ts.start_dtm) = @Month 

--accounting months 2012 
AND (@month_ref = 81201 AND ts.start_dtm Between '2011-11-28' AND '2012-01-01') 
    or (@month_ref = 81202 AND ts.start_dtm Between '2012-01-02' AND '2012-01-29') 
    or (@month_ref = 81203 AND ts.start_dtm Between '2012-01-30' AND '2012-02-26') 
    or (@month_ref = 81204 AND ts.start_dtm Between '2012-02-27' AND '2012-04-01') 
    or (@month_ref = 81205 AND ts.start_dtm Between '2012-04-02' AND '2012-04-29') 
    or (@month_ref = 81206 AND ts.start_dtm Between '2012-04-30' AND '2012-05-27') 
    or (@month_ref = 81207 AND ts.start_dtm Between '2012-05-28' AND '2012-06-01') 
    or (@month_ref = 81208 AND ts.start_dtm Between '2012-07-02' AND '2012-07-29') 
    or (@month_ref = 81209 AND ts.start_dtm Between '2012-07-30' AND '2012-08-26') 
    or (@month_ref = 81210 AND ts.start_dtm Between '2012-08-27' AND '2012-09-30') 
    or (@month_ref = 81211 AND ts.start_dtm Between '2012-10-01' AND '2012-10-28') 
    or (@month_ref = 81212 AND ts.start_dtm Between '2012-10-29' AND '2012-11-25') 


GROUP BY tsks.grouping_ref, ttg.description, 
DATENAME(MONTH, ts.start_dtm), 
DATENAME(YEAR, ts.start_dtm) 
ORDER BY grouping_desc 

本質上其過濾結果基礎上的日期範圍,然後分組的結果是這樣的:

Job Group | Month | Booked Hours 

    Test | Feb 12 | 7 

然後,用戶在測試點擊,他們會看到預訂了7小時的報告。 我想根據日期範圍進行分組?

我知道這會在本月:

DATENAME(MONTH, ts.start_dtm), 
DATENAME(YEAR, ts.start_dtm) 

但按日期範圍組只能顯示出來,如果有結果,即測試可能在範圍1,因此它會顯示否則不顯示日期範圍。

任何想法?

回答

2

這對我來說仍然不是100%清楚。我會盡我所能。

我正在使用日期表,以及您的業務使用的month_ref和month_name。正如你所看到的,填充日期表後,它將包含你將需要的日期的所有數據。在SELECT和GROUP部分都使用month_name。

注意使用日期表後查詢變得簡單多了。

CREATE TABLE Dates(
    TheDate  DATE NOT NULL, 
    month_ref  INT  NOT NULL, 
    month_name VARCHAR(10) 
) 

INSERT INTO Dates(TheDate, month_ref, month_name) VALUES 
('20120312', 81204, 'March 2012') 

DECLARE @month_ref INT 
SET @month_ref = 81204 

SELECT tsks.grouping_ref, 
    ttg.description AS grouping_desc, 
    SUM(ts.booked_time) AS booked_time_total, 
    Dates.MyDisplayValue AS month_name, 
    Dates.month_ref AS month_ref 
FROM timesheets ts 
    JOIN timesheet_categories cat 
    ON ts.timesheet_cat_ref = cat.timesheet_cat_ref 
    JOIN timesheet_tasks tsks 
    ON ts.task_ref = tsks.task_ref 
    JOIN timesheet_task_groupings ttg 
    ON tsks.grouping_ref = ttg.grouping_ref 
    INNER JOIN Dates 
    ON ts.start_dtm = Dates.TheDate 
WHERE ts.status IN(1, 2) --Booked and approved 
    AND cat.is_leave_category = 0 --Ignore leave 
    AND Dates.month_ref = @month_ref 
GROUP BY tsks.grouping_ref, 
    ttg.description, 
    Dates.MyDisplayValue, 
    Dates.month_ref 
ORDER BY grouping_desc 
+0

謝謝..這對我來說很好。 – 2012-03-13 09:11:29

2

我不明白你的問題。

看到

AND (@month_ref = 81201 AND ts.start_dtm Between '2011-11-28' AND '2012-01-01') 
    or (@month_ref = 81202 AND ts.start_dtm Between '2012-01-02' AND '2012-01-29') 

後,我記得我們的代碼是如何2年前樣子。您可以考慮將DatesTable添加到數據庫中。在我們的公司中,我們存儲自公司成立至今的所有日期以及未來20年的日期。每天都有許多屬性(尺寸,列,無論你稱之爲什麼)IsWeekDay,IsHolliday,Quarter,YearNr,MonthNr,WeekNr,DayName,MonthName,......你可以添加你的業務需要的任何額外的列。

只需將此活動的日期與此表一起加入,然後選擇您需要的任何維度,例如季度和年度。您可以使用這些來對結果進行分組。

我花了不到半天的時間向谷歌一些開始查詢以獲得此表填充。我們首先爲我們的數據倉庫做好了準備,但是現在每個部門都在使用它來計算工作日,週六,週日,節假日的工資支票;基於周,月,年,季度的財務報告...

它簡化了我們的查詢了很多。

+0

感謝您與我分享。我知道創建一張獨立桌子的好習慣。這個問題是由小組? – 2012-03-12 13:30:33

+0

我的問題是,如何組/顯示日期範圍而不是顯示月份。 – 2012-03-12 13:31:43

1

我第二什麼Wim說,因爲它是完整的解決方案。

select dr.Name ... 
... 
inner join date_ranges dr 
    on ts.start_dtm between dr.StartDate and dr.EndDate 
    and dr.ID = @month_ref 
... 
group by dr.Name ... 

這樣你就不必更改查詢:如果您正在尋找修補當前的問題,如果你創建的範圍及名稱表,通過一系列的名字加入和組,你會過得更好每年,並保留以前的副本。

編輯:通過一系列

你想重複你的過濾組分組。你只是過濾一個範圍,所以你不需要爲此分組。放入選擇列表類似

case @month_ref when '81201' then '1 2012' when '81202' then '2 2012' etc end. 

如果你想在case語句更靈活的解決方案檢查start_dtm這樣的:

case when start_dtm between ... then '1 2012' .... end. 

但隨後你將不得不重複這組。我給你的第一個解決方案將爲你節省大量的複製粘貼和錯誤查找。

+0

我無法再使用month_ref,我需要創建一個不同的名稱。你能幫助我嗎?因爲結果的日期範圍是硬編碼的。這其實不是問題。 – 2012-03-12 13:30:11

+0

我想我誤解了你的問題。你能發佈你得到的結果嗎?他們應該看起來像什麼? – 2012-03-12 13:34:59

+0

結果在原帖中是我的朋友。 工作組| |月|預訂時間 測試| 2月12日| 7 – 2012-03-12 13:36:13