我有以下存储过程:
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范围内,因此它会显示,否则不显示日期范围。
有什么想法吗?
答案 0 :(得分: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,......你可以添加你的业务所需的任何额外列。
只需将活动日期加入此表格,然后选择您需要的任何维度,例如季度和年份。您可以使用它们对结果进行分组。
我花了不到半天的时间向谷歌开始查询以填充此表。我们首先为我们的数据仓库做了这个,但是现在关于每个部门都在使用它来计算工作日,周六,周日,节假日工作的薪酬支票;基于周,月,年,季度的财务报告......
它简化了我们的查询。
答案 1 :(得分:2)
我仍然没有100%清楚你所追求的是什么。我会尽我所能。
我正在使用Dates表,其中包含您的公司使用的month_ref和month_name。如您所见,在填充Dates表后,它会保存您需要的日期周围的所有数据。在SELECT和GROUP部分中使用month_name。
注意使用Dates表后查询变得多么简单。
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
答案 2 :(得分: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.
但是你必须在分组中重复它。我给你的第一个解决方案可以为你节省大量的复制粘贴和错误搜索。