2016-04-18 8 views
1

Ich benutze SQL Server 2014 und ich habe eine Tabelle Attendance. Diese Tabelle hat 2 Spalten AttdDate und Status. Ich möchte eine gespeicherte Prozedur erstellen, die eine Liste von Daten zwischen 2 Daten, AttdDate und status zurückgibt. Und wenn die AttdDate ist in dieser Liste (Datumsliste) sollte der Status wahr sein sonst sollte der Status falsch sein.Erhalten Sie alle Daten zwischen 2 Daten in SQL Server gespeicherte Prozedur

Irgendwelche Ratschläge? Dank

Antwort

1
CREATE PROCEDURE sp_Attendance @Start DATETIME, @End DATETIME 
AS 
BEGIN 
    DECLARE @NumDays INT; 
    -- This will give you the number of days between your start date and end date. 
    SELECT @NumDays = DATEDIFF(DAY, @Start, @End) + 1; 
    WITH CTE AS (
     SELECT TOP (@Numdays) 
      /* 
      ROW_NUMBER() OVER (ORDER BY a.object_id) will give you an integer from 1 to @NumDays becuase of TOP (@NumDays) 
      ROW_NUMBER() OVER (ORDER BY a.object_id) - 1 will give you an integer from 0 to @NumDays 
      DATEADD(DAY, ROW_NUMBER(), @Start) -- This will add the integer from the row number statement to your start date. 
      i.e. 
       @Start + 0 
       @Start + 1 
       @Start + 2 
       etc 
       etc 
       @Start + @NumDays   
      */ 
      DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY a.object_id) - 1, @Start) AS AttdDate 
     FROM 
      sys.all_columns a 
     CROSS JOIN 
      sys.all_columns b) 
    SELECT 
     c.AttdDate, 
     CASE WHEN a.AttdDate IS NOT NULL THEN 1 ELSE 0 END AS Status 
    FROM 
     CTE c 
    LEFT JOIN 
     Attendance a 
      ON c.AttdDate = a.AttdDate; 
END; 
+0

Das ist genial. Wirklich hast du meine Zeit gerettet. Vielen Dank – prime

+0

Ich bin wirklich dankbar. aber bitte diesen Teil "MIT CTE AS ( SELECT TOP (@Numdays) DATEADD (TAG, ROW_NUMBER() OVER (ORDER BY a.object_id) erklären - 1, @Start) AS AttdDate VON sys.all_columns ein CROSS JOIN sys.all_columns b) " – prime

+0

Ich habe einige Kommentare im Code hinzugefügt, um zu erklären. –

0

Sie können eine rekursive Abfrage für diesen Einsatz:

WITH q(d) AS 
     (
     SELECT @mindate 
     UNION ALL 
     SELECT DATEADD(day, 1 d) 
     FROM q 
     WHERE d < @maxdate 
     ) 
SELECT * 
FROM q 
OPTION (MAXRECURSION 0) 

würde jedoch seine Leistung für größere Reichweiten ziemlich schlecht.

schaffe ich in der Regel nur eine Tabelle mit allen möglichen Daten bis zum Jahr 2100 in meiner SQL Server-Datenbanken:

SELECT * 
FROM dates 
WHERE d BETWEEN @mindate AND @maxdate