2017-01-29 6 views
1

Ich versuche, einen Bericht über Arbeitsaktivitäten zu erstellen. Wo die folgenden Bedingungen festgelegt sind.SQL-Nummer von columngroup

Wenn einer in einem nachfolgenden Datumsbereich abwesend ist, dann als gleiche Abwesenheitsgruppe markieren, sonst als neue Abwesenheitsgruppe markieren.

Also, wenn ich am Montag nicht anwesend bin, Dienstag, Mittwoch, ist, dass eine Gruppe von einem

1.

markiert Wenn ich dann am Donnerstag, bei der Arbeit, aber abwesend wieder Freitag, als Freitag markiert mit Gruppe2.

Wenn ich am Montag noch abwesend bin dann, dass noch Gruppe 2.

Die Beispieldaten zur Verfügung gestellt ist, ist die Art der Daten, die ich von den Shift-Scheduling-Tabellen bekomme ich habe, abgesehen von Identifikatoren, wenn ein besondere Aktivität ist Abwesenheit oder Nicht-Abwesenheit. Es gibt natürlich mehr als eine Reihe von Initialen an jedem beliebigen Tag zusammen mit verschiedenen Arten von Aktivitäten und Absence-Aktivitäten.

Ich habe versucht, ein minimales Arbeitsbeispiel für die Eingabedaten und das gewünschte Ergebnis zu liefern. Hoffentlich kann ich ein paar Hinweise dazu bekommen.

USE Sandbox 
DROP TABLE Data /* Clean up after ourselves. */ 
CREATE TABLE Data (/* Create table */ 
[Date] DATE, 
Initials VARCHAR(10), 
Activity VARCHAR(255), 
ActivityType VARCHAR(255) 
); 

/* Insert data */ 
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-05','PersonA','Work','Work') 
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-06','PersonA','Work','Work') 
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-07','PersonA','AbsenceActivity','Absence') 
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-08','PersonA','AbsenceActivity','Absence') 
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-09','PersonA','AbsenceActivity','Absence') 
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-10',NULL,NULL,'NoShift') 
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-11',NULL,NULL,'NoShift') 
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-12','PersonA','AbsenceActivity','Absence') 
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-13','PersonA','Work','Work') 
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-14','PersonA','AbsenceActivity','Absence') 
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-15','PersonA','AbsenceActivity','Absence') 

Diese Art gibt mir, was ich will, aber ich kann den rownumber oder Rang oder DENSE_RANK zurückgesetzt wird, nicht erhalten, wenn eine neue Gruppe eingeführt wird. Gewünschtes Ergebnis nach unten.

SELECT [Date] 
      ,Initials 
      ,activity 
      ,ActivityType 
      ,rank() OVER (PARTITION BY data.activitytype, Initials ORDER BY data.date,data.initials) rownumber 
    FROM data 
    GROUP BY data.date, data.initials, activity,ActivityType 
ORDER BY date 

Gewünschtes Ergebnis - Vollständige Arbeitstätigkeit Datumsbereich

SELECT '2016-12-05' as [Date] ,'PersonA' AS [Initials] ,'Work'    AS [Activity] ,'Work'  AS [ActivityType] ,'0' AS [identifier] union all 
SELECT '2016-12-06' as [Date] ,'PersonA' AS [Initials] ,'Work'    AS [Activity] ,'Work'  AS [ActivityType] ,'0' AS [identifier] union all 
SELECT '2016-12-07' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'1' AS [identifier] union all 
SELECT '2016-12-08' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'1' AS [identifier] union all 
SELECT '2016-12-09' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'1' AS [identifier] union ALL 
SELECT '2016-12-12' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'1' AS [identifier] union all 
SELECT '2016-12-13' as [Date] ,'PersonA' AS [Initials] ,'Work'    AS [Activity] ,'Work'  AS [ActivityType] ,'0' AS [identifier] union all 
SELECT '2016-12-14' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'2' AS [identifier] union all 
SELECT '2016-12-15' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'2' AS [identifier]  

Alternative Ergebnis 1 Full Datum-Bereich einschließlich Weekens oder Nicht-Arbeitsdaten

SELECT '2016-12-05' as [Date] ,'PersonA' AS [Initials] ,'Work'    AS [Activity] ,'Work'  AS [ActivityType] ,'0' AS [identifier] union all 
SELECT '2016-12-06' as [Date] ,'PersonA' AS [Initials] ,'Work'    AS [Activity] ,'Work'  AS [ActivityType] ,'0' AS [identifier] union all 
SELECT '2016-12-07' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'1' AS [identifier] union all 
SELECT '2016-12-08' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'1' AS [identifier] union all 
SELECT '2016-12-09' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'1' AS [identifier] union ALL 
SELECT '2016-12-10' as [Date] ,NULL  AS [Initials] ,'Weekend' AS [Activity] ,'noShift' AS [ActivityType] ,NULL AS [identifier] union ALL 
SELECT '2016-12-11' as [Date] ,NULL  AS [Initials] ,'Weekend' AS [Activity] ,'noShift' AS [ActivityType] ,NULL AS [identifier] union ALL 
SELECT '2016-12-12' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'1' AS [identifier] union all 
SELECT '2016-12-13' as [Date] ,'PersonA' AS [Initials] ,'Work'    AS [Activity] ,'Work'  AS [ActivityType] ,'0' AS [identifier] union all 
SELECT '2016-12-14' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'2' AS [identifier] union all 
SELECT '2016-12-15' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'2' AS [identifier]  

Alternative Ergebnis 2 Nur Daten enthalten, wo eine Reihe von Initialen hat Aktivitäten auf

SELECT '2016-12-07' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'1' AS [identifier] union all 
SELECT '2016-12-08' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'1' AS [identifier] union all 
SELECT '2016-12-09' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'1' AS [identifier] union all 
SELECT '2016-12-10' as [Date] ,NULL AS [Initials] ,'Weekend' AS [Activity] ,'noShift' AS [ActivityType] ,NULL AS [identifier] union ALL 
SELECT '2016-12-11' as [Date] ,NULL AS [Initials] ,'Weekend' AS [Activity] ,'noShift' AS [ActivityType] ,NULL AS [identifier] union ALL 
SELECT '2016-12-12' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'1' AS [identifier] union all 
SELECT '2016-12-14' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'2' AS [identifier] union all 
SELECT '2016-12-15' as [Date] ,'PersonA' AS [Initials] ,'AbsenceActivity' AS [Activity] ,'Absence' AS [ActivityType] ,'2' AS [identifier]  

Antwort

1

Mit with (common table expression) und können wir Zeilennummern für die Partitionen (Initials, activitytype) und (Initials) generieren.

Durch den Vergleich können wir aufeinanderfolgende Blöcke nach Aktivität gruppieren und sie mit dense_rank() nummerieren.

Um alle "Arbeit" in 0 zu konvertieren, habe ich gerade einen Ausdruck case in der endgültigen Abfrage verwendet.

rextester: http://rextester.com/AYR27547

with cte as (
    select 
     [Date] 
     , Initials 
     , activity 
     , ActivityType 
     , irn=row_number() over (
      partition by Initials 
      order by [date] 
     ) 
     , atrn=row_number() over (
      partition by Initials, activitytype 
      order by [date] 
     ) 
    from [data] d 
    group by [Date], Initials, Activity, ActivityType 
    ) 

select 
     [date] 
    , Initials 
    , activity 
    , ActivityType 
    , ActivityGroup = case 
     when ActivityType='Work' 
      then 0 
     else dense_rank() over (
      partition by Initials, ActivityType 
      order by irn-atrn 
      ) 
     end 
    from cte 
    order by [date] 

Ergebnisse:

+------------+----------+-----------------+--------------+---------------+ 
| date | Initials | activity  | ActivityType | ActivityGroup | 
+------------+----------+-----------------+--------------+---------------+ 
| 2016-12-05 | PersonA | Work   | Work   |    0 | 
| 2016-12-06 | PersonA | Work   | Work   |    0 | 
| 2016-12-07 | PersonA | AbsenceActivity | Absence  |    1 | 
| 2016-12-08 | PersonA | AbsenceActivity | Absence  |    1 | 
| 2016-12-09 | PersonA | AbsenceActivity | Absence  |    1 | 
| 2016-12-10 | NULL  | NULL   | NoShift  |    1 | 
| 2016-12-11 | NULL  | NULL   | NoShift  |    1 | 
| 2016-12-12 | PersonA | AbsenceActivity | Absence  |    1 | 
| 2016-12-13 | PersonA | Work   | Work   |    0 | 
| 2016-12-14 | PersonA | AbsenceActivity | Absence  |    2 | 
| 2016-12-15 | PersonA | AbsenceActivity | Absence  |    2 | 
+------------+----------+-----------------+--------------+---------------+ 
Verwandte Themen