sql >> Database >  >> RDS >> Sqlserver

sql-server met ontbrekende datums

Ik zou je aanraden om een ​​table valued function te gebruiken om alle dagen tussen 2 geselecteerde datums als een tabel te krijgen (Probeer het uit in deze viool) :

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

(Ik voeg een eenvoudige tabelconfiguratie toe voor eenvoudige kopieer- en plaktests)

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'

nu kunt u eenvoudig controleren op welke dagen er geen bezoek is geweest als u de "grensdagen" kent, zoals deze:

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')

Of als u alle dagen wilt weten waarop een site niet is bezocht, kunt u deze zoekopdracht gebruiken:

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

Even een kanttekening:het lijkt erop dat je wat duplicatie in je tabel hebt (niet genormaliseerd) siteName zou echt in een aparte tabel moeten gaan en alleen worden verwezen vanuit SiteVisit



  1. Hoe commentaar te geven in SQL

  2. Hoe kan ik een tabel van een opgeslagen procedure naar een gegevenstabel ophalen?

  3. PreparedStatement-vraag in Java tegen Oracle

  4. Null individuele waarden retourneren met postgres tablefunc crosstab()