2017-06-01 14 views
0

Ich benötige einige Ideen bezüglich einer effizienten Methode zum Erstellen von Zeilen pro Anzahl in einer Häufigkeitsspalte in SQL. (SQL Server 2016)Erstellen von geänderten Zeilen aus der Häufigkeitsspalte in T-SQL

Die Daten:
Ich habe eine Tabelle mit den Daten in Kranken rief die Menschen und wie viele Tage sie sagten, sie waren im Begriff fehlen:

BEGIN_DATE    DAYS_SICK 
2011-01-01 00:00:00.000 3 
2011-01-01 00:00:00.000 3 
2011-01-01 00:00:00.000 1 
2011-01-02 00:00:00.000 2 
2011-01-02 00:00:00.000 3 
2011-01-04 00:00:00.000 4 
2011-01-04 00:00:00.000 4 
2011-01-04 00:00:00.000 3 

ich das übersetzen wollen ein Tisch, wo jede Reihe einen Tag im Jahr darstellt und ich die Anzahl der Menschen, die an diesem Tag krank sind, zähle.

DATE      PEOPLE_SICK 
2011-01-01 00:00:00.000 3 
2011-01-02 00:00:00.000 4 
2011-01-03 00:00:00.000 4 
2011-01-04 00:00:00.000 4 
2011-01-05 00:00:00.000 3 
2011-01-06 00:00:00.000 3 
2011-01-07 00:00:00.000 2 

So zum Beispiel:

  • Für 2011-01-01 gab es drei Personen, die sich krank gemeldet, 2 krank gemeldet für 3 Tage und eine nur für diesen Tag. Der Ausgang ist 3.
  • Jetzt am 2011-01-02 andere 2 (verschiedene) Personen angerufen krank, aber es gab 2 Personen vom Vortag, die sagten, dass sie an diesem Tag auch vermissen würden, so ist der Ausgang 4.
  • Keine Person angerufen am 2011-01-03 aber es gab 2 Personen von vor 2 Tagen, die sagten, sie würden diesen Tag plus 2 Personen vom Vortag vermissen. Der Ausgang ist 4.
  • Etc ...

ich derzeit dies tue, indem sie in den Eingang durch jede der Zeilen laufen und dann über die Frequenzen Looping, das Hinzufügen oder Aktualisieren von Zeilen auf der neuen Tabelle als notwendig aber es dauert eine obszöne Zeit.

Gibt es andere Möglichkeiten, dies effizienter zu tun?

Antwort

1

Dies beschäftigt sich nicht mit Wochenenden, aber können Sie beginnen. Auch wenn es eine Abfrage gab, die oft lief, würde ich eine DATE DIM Tabelle erstellen und sie anstelle des Datums CTE verwenden. Where I got the DATE DIM code from.

CREATE TABLE #test (ID int IDENTITY(1,1), BEGIN_DATE datetime, DAYS_SICK int); 

DECLARE @StartDate datetime = '2011-01-01' 
, @CutoffDate datetime = '2011-01-10'; 

INSERT INTO #test (BEGIN_DATE, DAYS_SICK) 
VALUES 
('2011-01-01 00:00:00.000', 3), 
('2011-01-01 00:00:00.000', 3), 
('2011-01-01 00:00:00.000', 1), 
('2011-01-02 00:00:00.000', 2), 
('2011-01-02 00:00:00.000', 3), 
('2011-01-04 00:00:00.000', 4), 
('2011-01-04 00:00:00.000', 4), 
('2011-01-04 00:00:00.000', 3); 

WITH Dates 
AS (SELECT d 
    FROM (
     SELECT d = DATEADD(DAY, rn - 1, @StartDate) 
     FROM (SELECT TOP (DATEDIFF(DAY, @StartDate, @CutoffDate)) rn = ROW_NUMBER() OVER (
        ORDER BY s1.[object_id]) 
      FROM sys.all_objects AS s1 
      CROSS JOIN sys.all_objects AS s2 
      ORDER BY s1.[object_id] 
      ) AS x 
     ) AS y 
    ) 
    ,SickRanges 
AS (
    SELECT BEGIN_DATE 
     ,DATEADD(DAY, DAYS_SICK - 1, BEGIN_DATE) END_DATE 
    FROM #test 
    ) 
SELECT d.d [DATE] 
    ,count(1) PEOPLE_SICK 
FROM SickRanges sr 
JOIN Dates d ON d.d BETWEEN sr.BEGIN_DATE AND sr.END_DATE 
GROUP BY d.d 
ORDER BY d.d 

DROP TABLE #test 
Verwandte Themen