sql server displaying missing dates

前端 未结 4 1662
盖世英雄少女心
盖世英雄少女心 2020-12-04 01:51
SiteVisitID     siteName        visitDate
------------------------------------------------------    
   1            site1           01/03/2014
   2            Site2         


        
4条回答
  •  清歌不尽
    2020-12-04 02:28

    I would recommend you use a table valued function to get you all days in between 2 selected dates as a table (Try it out in this fiddle):

    CREATE FUNCTION dbo.GetAllDaysInBetween(@FirstDay DATETIME, @LastDay DATETIME)
    RETURNS @retDays TABLE 
    (
        DayInBetween DATETIME
    )
    AS 
    BEGIN
        DECLARE @currentDay DATETIME
        SELECT @currentDay = @FirstDay
    
        WHILE @currentDay <= @LastDay
        BEGIN
    
            INSERT @retDays (DayInBetween)
                SELECT @currentDay
    
            SELECT @currentDay = DATEADD(DAY, 1, @currentDay)
        END 
    
        RETURN
    END
    

    (I include a simple table setup for easy copypaste-tests)

    CREATE TABLE SiteVisit (ID INT PRIMARY KEY IDENTITY(1,1), visitDate DATETIME, visitSite NVARCHAR(512))
    
    INSERT INTO SiteVisit (visitDate, visitSite)
        SELECT '2014-03-11', 'site1'
        UNION
        SELECT '2014-03-12', 'site1'
        UNION
        SELECT '2014-03-15', 'site1'
        UNION
        SELECT '2014-03-18', 'site1'
        UNION
        SELECT '2014-03-18', 'site2'
    

    now you can simply check what days no visit occured when you know the "boundary days" such as this:

    SELECT
            DayInBetween AS missingDate,
            'site1' AS visitSite
        FROM dbo.GetAllDaysInBetween('2014-03-11', '2014-03-18') AS AllDaysInBetween
        WHERE NOT EXISTS 
            (SELECT ID FROM SiteVisit WHERE visitDate = AllDaysInBetween.DayInBetween AND visitSite = 'site1')
    

    Or if you like to know all days where any site was not visited you could use this query:

    SELECT
            DayInBetween AS missingDate,
            Sites.visitSite
        FROM dbo.GetAllDaysInBetween('2014-03-11', '2014-03-18') AS AllDaysInBetween
        CROSS JOIN (SELECT DISTINCT visitSite FROM SiteVisit) AS Sites
        WHERE NOT EXISTS
            (SELECT ID FROM SiteVisit WHERE visitDate = AllDaysInBetween.DayInBetween AND visitSite = Sites.visitSite)
        ORDER BY visitSite
    

    Just on a side note: it seems you have some duplication in your table (not normalized) siteName should really go into a separate table and only be referenced from SiteVisit

提交回复
热议问题