为什么记录在录入日期没有得到纠察?

时间:2019-06-10 11:21:20

标签: sql sql-server tsql sql-server-2012

我很早以前就编写了这个查询,它正在工作,但现在却不行。

CREATE PROCEDURE [dbo].[WeeklyReport]
AS
BEGIN
    CREATE TABLE #temp
        (
            Area VARCHAR(20),
            NoOfInspec INT
        )

    INSERT INTO #temp
        SELECT DISTINCT
            Area, COUNT(*) AS NoOfInsp 
        FROM 
            EngineeringData E, PIRTaskList T
        WHERE
            E.EnggDataID = t.EnggDataID 
            AND T.NextInspDate BETWEEN (DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), GETDATE()))
                                   AND (DATEADD(DAY, 7 - DATEPART(WEEKDAY, GETDATE()), GETDATE()))
        GROUP BY
            Area

    SELECT
        t.Area, t.NoOfInspec AS Planned, SecTable.NoOfInsp AS Executed 
    FROM
        #temp t
    INNER JOIN
        (SELECT DISTINCT
             Area, COUNT(*) AS NoOfInsp  
         FROM
             tblScheduleHistory 
         WHERE
             EntryDate BETWEEN (DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), GETDATE()))
                           AND (DATEADD(DAY, 7 - DATEPART(WEEKDAY, GETDATE()), GETDATE()))    
        GROUP BY
            Area) SecTable ON SecTable.Area = t.Area
    ORDER BY 
        t.Area
END

几条记录的entrydate日期是

2019-10-06
2019-09-06
2019-11-06

要求是如果有1个日期,则选择整周的记录。

2 个答案:

答案 0 :(得分:1)

DATEPART(WEEKDAY, GETDATE())取决于SET DATEFIRST选项,该选项也可以使用SET LANGUAGE进行更改。还可以使用sp_configure在服务器级别配置默认语言。

例如,请尝试以下操作以查看不同的结果:

DECLARE @CurrentDate DATE='2019-06-16'

SET LANGUAGE ENGLISH
SELECT  DATEPART(WEEKDAY, @CurrentDate), 
        DATEADD(DAY, 1 - DATEPART(WEEKDAY, @CurrentDate), @CurrentDate), 
        DATEADD(DAY, 7 - DATEPART(WEEKDAY, @CurrentDate), @CurrentDate)
-- returns 1, 2019-06-16, 2019-06-22

SET LANGUAGE BRITISH
SELECT  DATEPART(WEEKDAY, @CurrentDate), 
        DATEADD(DAY, 1 - DATEPART(WEEKDAY, @CurrentDate), @CurrentDate), 
        DATEADD(DAY, 7 - DATEPART(WEEKDAY, @CurrentDate), @CurrentDate)
-- returns 7, 2019-06-10, 2019-06-16

要使代码以相同的方式工作,而无论使用SET DATEFIRST选项如何,都可以通过以下方式添加@@DATEFIRST

DECLARE @CurrentDate DATE='2019-06-16'

SET LANGUAGE ENGLISH

SELECT  (@@DATEFIRST-1 + DATEPART(WEEKDAY, @CurrentDate))%7+1,
        DATEADD(DAY, 1 - ((@@DATEFIRST-1 + DATEPART(WEEKDAY, @CurrentDate))%7+1), @CurrentDate), 
        DATEADD(DAY, 7 - ((@@DATEFIRST-1 + DATEPART(WEEKDAY, @CurrentDate))%7+1), @CurrentDate)
-- returns 1, 2019-06-16, 2019-06-22

SET LANGUAGE BRITISH

SELECT  (@@DATEFIRST-1 + DATEPART(WEEKDAY, @CurrentDate))%7+1,
        DATEADD(DAY, 1 - ((@@DATEFIRST-1 + DATEPART(WEEKDAY, @CurrentDate))%7+1), @CurrentDate), 
        DATEADD(DAY, 7 - ((@@DATEFIRST-1 + DATEPART(WEEKDAY, @CurrentDate))%7+1), @CurrentDate)
-- returns 1, 2019-06-16, 2019-06-22

答案 1 :(得分:0)

感谢@Razvan Socol的见识。

我将尽力澄清我和拉兹瓦布都认为的问题的症结所在。

最后的代码会迭代一组日期,输出在该日期的一周内计算出的上下边界。

@Razvan Socol解决方案可能重写为

DECLARE @dt date = '20190610'

-- Week starts on sundays
PRINT dateadd(dd, 0 - (datepart(weekday, @dt) + @@datefirst - 1) % 7, @dt)
PRINT dateadd(dd, 6 - (datepart(weekday, @dt) + @@datefirst - 1) % 7, @dt)

-- Week starts on mondays
PRINT dateadd(dd, 0 - (datepart(weekday, @dt) + @@datefirst - 2) % 7, @dt)
PRINT dateadd(dd, 6 - (datepart(weekday, @dt) + @@datefirst - 2) % 7, @dt)

这里遵循整个POC。

SET DATEFIRST 4

DECLARE @datefirst int = 7 -- 1 weeks start on mondays, 7 weeks start on sundays
DECLARE @dtStart date = '20190605'
DECLARE @dtEnd   date = '20190619'

DECLARE @result table(
    dt varchar(255),
    deltaL int, deltaH int,
    boundaryL varchar(255), boundaryH varchar(255)
)

DECLARE @deltaL    int,  @deltaH     int
DECLARE @boundaryL date, @boundaryH  date

WHILE @dtStart <= @dtEnd
BEGIN
    -- Computes DATEPART as ISO 8601, where Monday == 1,
    -- adjusting to @dateFirst
    DECLARE @iso8601 int =
        (
            datepart(weekday, @dtStart) - /* shifted to base 0 */ 1 + 
            @@datefirst                 - /* shifted to base 0 */ 1 +
            --
            (7 - @datefirst + 1) -- Shifted for @datefirst
        ) % 7 + 1

    SET @deltaL = 1 - @iso8601
    SET @deltaH = 7 - @iso8601
    --
    SET @boundaryL = dateadd(dd, @deltaL, @dtStart)
    SET @boundaryH = dateadd(dd, @deltaH, @dtStart)

    INSERT INTO @result
    VALUES(
        convert(varchar, @dtStart, 120) + ' ' + datename(weekday, @dtStart),
        @deltaL, @deltaH,
        convert(varchar, @boundaryL, 120) + ' ' + datename(weekday, @boundaryL),
        convert(varchar, @boundaryH, 120) + ' ' + datename(weekday, @boundaryH)
    )

    SET @dtStart = dateadd(dd, 1, @dtStart)
END

SELECT * FROM @result