使用 Linq to SQL 或纯 SQL 将日期范围内的值分组为周
我有一个表格,其形式为:
StartDate[date], EndDate[date], HoursPerWeek[int]
其填充方式有点像这样:
StartDate | EndDate | HoursPerWeek
01/01/2010 | 31/12/2010 | 37
01/01/2010 | 31/03/2010 | 16
05/03/2010 | 31/10/2010 | 9
我需要生成一个表格,该表格按周详细列出给定日期范围内的工作小时数。
理想情况下,我会在 linq to sql 中执行此操作,但如果我需要调用存储过程也没关系。我还没有真正了解如何实施这一点。
我该如何开始呢?
更新
我最终将其编写为存储过程,它有效,但在我看来这不是一个漂亮的解决方案。
CREATE PROCEDURE prcGetHoursWorked
(
@StartDate DATE,
@EndDate DATE
)
AS
CREATE TABLE #Results
(
WeekStart DATE,
TotalHours INT
)
DECLARE @WeekOffset INT
DECLARE @FirstDayOfStartWeek DATE
DECLARE @HoursThisWeek INT
SET @WeekOffset = 0
SET @FirstDayOfStartWeek = dbo.fnc_StartOfWeek(@StartDate, 2);
WHILE (DATEDIFF(wk, @StartDate, @EndDate) > @WeekOffset)
BEGIN
SELECT @HoursThisWeek = SUM(HoursPerWeek) FROM StaffCost
WHERE NOT (
Start> DATEADD(wk, @WeekOffset + 1, @FirstDayOfStartWeek)
OR
[End] < DATEADD(wk, @WeekOffset, @FirstDayOfStartWeek)
)
INSERT INTO #Results
VALUES(DATEADD(wk, @WeekOffset, @FirstDayOfStartWeek), @HoursThisWeek)
SET @WeekOffset = @WeekOffset + 1
END
SELECT * FROM #Results
是否可以将其作为基于集合的操作来执行,或者更好地直接从 linq 到 sql?
I have a table that is of the form:
StartDate[date], EndDate[date], HoursPerWeek[int]
and is filled a bit like this:
StartDate | EndDate | HoursPerWeek
01/01/2010 | 31/12/2010 | 37
01/01/2010 | 31/03/2010 | 16
05/03/2010 | 31/10/2010 | 9
What I need to produce is a table that gives a breakdown on a week by week basis of the number of hours worked for a given date range.
Ideally I'd do this in linq to sql, but if I need to call a stored procedure that's fine. I haven't really got the first clue how to go about implementing this.
How can I get started with this?
UPDATE
I've ended up writing this as a store procedure, which works, but to my eyes is not a pretty solution.
CREATE PROCEDURE prcGetHoursWorked
(
@StartDate DATE,
@EndDate DATE
)
AS
CREATE TABLE #Results
(
WeekStart DATE,
TotalHours INT
)
DECLARE @WeekOffset INT
DECLARE @FirstDayOfStartWeek DATE
DECLARE @HoursThisWeek INT
SET @WeekOffset = 0
SET @FirstDayOfStartWeek = dbo.fnc_StartOfWeek(@StartDate, 2);
WHILE (DATEDIFF(wk, @StartDate, @EndDate) > @WeekOffset)
BEGIN
SELECT @HoursThisWeek = SUM(HoursPerWeek) FROM StaffCost
WHERE NOT (
Start> DATEADD(wk, @WeekOffset + 1, @FirstDayOfStartWeek)
OR
[End] < DATEADD(wk, @WeekOffset, @FirstDayOfStartWeek)
)
INSERT INTO #Results
VALUES(DATEADD(wk, @WeekOffset, @FirstDayOfStartWeek), @HoursThisWeek)
SET @WeekOffset = @WeekOffset + 1
END
SELECT * FROM #Results
Is it possible to do this as a set based operation, or better still straight from linq to sql?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定我是否理解您期望的输出是什么样子。但我会尽力不让这阻止我提出建议。
如果您构建日历表,这样的查询通常很容易表达。但你正在寻找的可能不是。 (见下文。)
这是输出的一部分。我修剪了它。
我之前发布过基本日历的代码SO 上的表 (PostgreSQL 语法)。它不包括 ISO 周和年。如果您愿意,我稍后会在这里发布完整的代码。请告诉我。
此查询不执行的两件事
它不会尝试按比例计算小时数。例如,示例输入的最后一行的开始日期为 2010-03-05。该日期属于 ISO 第 9 周,即从 2010 年 3 月 1 日到 2010 年 3 月 7 日;我编写的查询不会尝试计算 ISO 第 9 周 9 小时的 3/7。
它与日历不一致。 ISO 周数对我来说很方便,因为它们已经在我的日历表中了。如果您构建自己的日历表,则可以按照您喜欢的任何方式定义它们。
I'm not sure I understand what you expect the output to look like. But I'll try not to let that stop me from offering a suggestion.
If you build a calendar table, queries like this are generally easy to express. But what you're looking for might not be. (See below.)
Heres's part of the output. I trimmed it.
I've previously posted code for a basic calendar table (PostgreSQL syntax) on SO. It doesn't include ISO weeks and years. If you want, I'll post the full code here later. Just let me know.
Two things this query doesn't do
It doesn't try to calculate pro rata hours. For example, the last line of your sample input has a start date of 2010-03-05. That date falls in ISO week 9, which runs from 2010-03-01 to 2010-03-07; the query I wrote doesn't try to calculate 3/7 of 9 hours for ISO week 9.
It doesn't align with the calendar. ISO week numbers were convenient for me, because they were already in my calendar table. If you build your own calendar table, you can define them any way you like.