3

我只是想问我如何才能实现在一个月内按周获取数据库中的记录?使用 sql 我真正的意思是当我输入 1 时,它将在一个月的第一周获得记录我今天做了很多研究,但似乎我找不到一个好的解决方案

继承人的代码:

DECLARE @MONTH int
DECLARE @YEAR int
DECLARE @WEEK int

SET @MONTH = 9
SET @YEAR = 2013
SET @WEEK = 1

SELECT RH.RepairOrderNumber FROM dbo.RepairOrderHeader RH
WHERE MONTH(RH.DateReleased) = @MONTH AND YEAR(RH.DateReleased) = @YEAR AND WEEK(RH.DateReleased) = @WEEK

我只想按月、年和周来获取记录,有什么方法和精确的代码可以做到这一点吗?

4

4 回答 4

0

WEEK返回一年中的第几周,从一周中的固定日期开始(即每个星期日)。您似乎想要每月的一周,我想这总是从每个月的第一天开始。

所以:

SELECT RH.RepairOrderNumber FROM dbo.RepairOrderHeader RH
WHERE  MONTH(RH.DateReleased) = @MONTH AND 
       YEAR(RH.DateReleased) = @YEAR AND 
       DAY(RH.DateReleased) / 7 + 1 = @WEEK
于 2013-09-26T11:35:37.543 回答
0

尽可能避免在 WHERE 子句中的列上使用函数。您立即失去了利用这些列上的索引的能力。下面的解决方案给出了与选择答案相同的结果,但性能要好得多:

DECLARE @MONTH INT = 9
DECLARE @YEAR INT = 2013
DECLARE @WEEK INT = 2

--1ST OF THE MONTH DECLARED
DECLARE @Date DATE = CAST(CAST(@Year AS VARCHAR(4)) + 
                    RIGHT('0' + CAST(@Month AS VARCHAR(2)), 2) + '01' AS DATE)

SET  @Date = DATEADD(WEEK, @Week - 1, DATEADD(DAY, 1 - DATEPART(WEEKDAY, @Date), @Date));

SELECT  RH.RepairOrderNumber 
FROM    dbo.RepairOrderHeader RH
WHERE   RH.DateReleased >= @Date
AND     RH.DateReleased < DATEADD(WEEK, 1, @Date);

所有这一切都是获取相关月份的第一天,然后找到该月第一天所在的一周的第一天。然后将声明的周数添加到该日期。

使用包含 6 年数据和每天 10 行的示例表(20,480 条记录,所以不是很多)和日期列上的索引,此执行计划和接受的答案如下(接受顶部,使用日期在底部):

在此处输入图像描述

在 SQL-Fiddle 上测试 DDL 和查询

这说明在使用WEEK(DateColumn) = @Week的时候根本没有用到索引,查询成本要高很多。根据表中数据的分布情况,这可能会产生巨大的差异,即使在我的示例中的一小部分数据中,它的效率也提高了 800%。

于 2013-09-26T11:45:38.077 回答
0

DATEPART(WEEK,)为您提供一年中的一周数,因此您只需计算当月的周数,计算当前日期周数与该月第一天的周数之间的差异:

WHERE MONTH(RH.DateReleased) = @MONTH 
  AND YEAR(RH.DateReleased) = @YEAR 
  AND DATEPART(WEEK,RH.DateReleased)
       -DATEPART(WEEK,DATEADD(DAY,-DAY(RH.DateReleased)+1,RH.DateReleased))+1 
       = @WEEK
于 2013-09-26T11:33:35.010 回答
0

我认为 '2013-08-26' - '2013-09-01' 是 9 月的第一周

DECLARE @MONTH int = 9
DECLARE @YEAR int = 2013
DECLARE @WEEK int = 1

DECLARE @from date= dateadd(day, datediff(day, -(@WEEK - 1)*7, 
       (dateadd(month, (@year-1900) * 12 + @month - 1 , 0)))/7*7 , 0)

SELECT RH.RepairOrderNumber 
FROM dbo.RepairOrderHeader RH
WHERE RH.DateReleased >= @from
and RH.DateReleased < dateadd(week, 1, @from)
于 2013-09-26T12:46:18.137 回答