【问题标题】:Why the records are not getting pickets for the entry date?为什么记录没有得到进入日期的纠察队?
【发布时间】:2019-06-10 11:21:20
【问题描述】:

我很久以前就写过这个查询,它可以工作,但现在不行了。

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 个日期,则要求选择整周的记录。

【问题讨论】:

  • 无需执行 SELECT DISTINCT,因为您的 GROUP BY 不会返回重复项。
  • 今日提示:切换到现代、明确的JOIN 语法。更容易编写(没有错误),更容易阅读(和维护),如果需要更容易转换为外连接
  • @CodingManiac 。 . . “正在工作”和“不工作”非常模糊,不能提供有用的信息。
  • @jarlh:我删除了它但没有用
  • @iamdave 我不同意在编辑中向 OP 的代码添加显式连接。因此,它不能代表 OP 的实际 SQL。

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


【解决方案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

【讨论】:

    【解决方案2】:

    感谢@Razvan Socol 提供的见解。

    我将尝试澄清 Razvab 和我都认为的问题的症结。

    最后的代码迭代一组日期,输出计算得出的日期周内的下限和上限。

    @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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多