CiAgICA8IS0tIExpbmtlZEluIC0tPgogICAgPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgogICAgICAgIF9saW5rZWRpbl9wYXJ0bmVyX2lkID0gIjEyMzUwNzMiOwogICAgICAgIHdpbmRvdy5fbGlua2VkaW5fZGF0YV9wYXJ0bmVyX2lkcyA9IHdpbmRvdy5fbGlua2VkaW5fZGF0YV9wYXJ0bmVyX2lkcyB8fCBbXTsKICAgICAgICB3aW5kb3cuX2xpbmtlZGluX2RhdGFfcGFydG5lcl9pZHMucHVzaChfbGlua2VkaW5fcGFydG5lcl9pZCk7CiAgICA8L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+CiAgICAgICAgKGZ1bmN0aW9uKCl7dmFyIHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgic2NyaXB0IilbMF07CiAgICAgICAgICAgIHZhciBiID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7CiAgICAgICAgICAgIGIudHlwZSA9ICJ0ZXh0L2phdmFzY3JpcHQiO2IuYXN5bmMgPSB0cnVlOwogICAgICAgICAgICBiLnNyYyA9ICJodHRwczovL3NuYXAubGljZG4uY29tL2xpLmxtcy1hbmFseXRpY3MvaW5zaWdodC5taW4uanMiOwogICAgICAgICAgICBzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGIsIHMpO30pKCk7CiAgICA8L3NjcmlwdD4KICAgIDxub3NjcmlwdD4KICAgICAgICA8aW1nIGhlaWdodD0iMSIgd2lkdGg9IjEiIHN0eWxlPSJkaXNwbGF5Om5vbmU7IiBhbHQ9IiIgc3JjPSJodHRwczovL3B4LmFkcy5saW5rZWRpbi5jb20vY29sbGVjdC8/cGlkPTEyMzUwNzMmZm10PWdpZiIgLz4KICAgIDwvbm9zY3JpcHQ+CiAgICA8IS0tIEVuZCBMaW5rZWRJbiAtLT4KICAgIA==
Generic filters
Exact matches only
Search in title
Search in excerpt
Search in content

Schicht im Schacht

Das Thema Zeit wurde bereits in etlichen Blogbeiträgen behandelt. Dennoch finden sich immer wieder neue Fälle, denen noch keine Beachtung geschenkt wurde. Eine relativ häufige Anforderung ist es zum Beispiel in Produktionsbetrieben den Tag in Schichtzeiten zu unterteilen. Das klingt auf den ersten Blick recht einfach. Man zieht einfach eine weitere Hierarchieebene ein, in der nach „Frühschicht“, „Spätschicht“ und „Nachtschicht“ unterschieden werden kann und schon scheint die Anforderung erfüllt zu sein.

Problematisch wird es, wenn eine Schicht an einem anderen Tag endet, als sie begonnen hat. Das folgende Beispiel erläutert das Grundproblem dieses Blogbeitrags.

Beispielhafter Schichtplan

Tabelle 1: Beispielhafter Schichtplan

In unserem Beispiel sind die Ereignisse, die analysiert werden sollen, Maschinenstörungen in der Produktion.
Die Nachtschicht beginnt hier am 13.01.2016 und endet erst am 14.01.2016. Das heißt, Maschinenstörungen, die aus dieser Schicht analysiert werden sollen, werden entweder dem 13.01. oder dem 14.01. zugeordnet. Wenn man sich alle Maschinenstörungen aus der Nachtschicht vom 13.01. ansehen möchte, erwartet man aber, auch die Störungen angezeigt zu bekommen, die am 14.01. zwischen 0:00 Uhr und 5:00 Uhr aufgetreten sind. Tatsächlich angezeigt bekommt man jedoch, sofern dieses Thema nicht weiter berücksichtigt wird, die Störungen, die am 13.01. zwischen 0:00 Uhr und 5:00 Uhr aufgetreten sind sowie die Störungen vom 13.01. von 21:00 Uhr bis zum Tagesende. Die Störungen am 13.01. zwischen 0:00 Uhr und 5:00 Uhr würde man jedoch wiederum in der Nachtschicht vom 12.01. erwarten.

Die Idee

Grundsätzlich ist in so einem Fall eine Unterscheidung nach dem tatsächlichen Datum und dem Arbeitstagdatum nötig. Es muss eine Entscheidung getroffen werden, welchem der beiden betroffenen Tage alle Maschinenstörungen zugeordnet werden sollen. Typischerweise wird man in unserer obigen Tabelle alle Störungen zwischen 0:00 Uhr und 5:00 Uhr dem Vortag zuordnen.
Das heißt: Ein Arbeitstag beginnt nicht um 0:00 Uhr und endet um 0:00 Uhr des Folgetages, sondern ein Arbeitstag beginnt um 5:00 Uhr und endet um 5:00 Uhr des Folgetages. Betrachtet man das tatsächliche Datum, darf keine Schichtbetrachtung vorgenommen werden!
Um das gewünschte Verhalten zu erhalten, muss eine ähnliche Logik angewandt werden, wie man sie von der DeltaMaster Modeler Funktion „Fiscal Year Offset“ kennt. Dem Datenmodell muss mitgeteilt werden, welche Stunden des Tages, welchem Tag und welcher Schicht zugeordnet werden. Dafür kann folgende T_S_-Tabelle genutzt werden:

T_S_Schicht-Tabelle zur Pflege der Schichtzeiten

Tabelle 2: T_S_Schicht-Tabelle zur Pflege der Schichtzeiten

Die Tabelle ordnet die jeweilige Stunde einer Schicht zu (Spalte SchichtID). In der Spalte Offset findet die Zuordnung zum richtigen Tag statt. Der jeweilige Wert von Offset muss zum tatsächlichen Datumswert dazugezählt werden, um den Arbeitstag zu erhalten. In unserem Fall wollen wir die Stunden von 0:00 Uhr bis 4:00 Uhr dem Vortag zuordnen. Daher beträgt der Offset-Wert –1.

Die Modellierung

Die nächste Frage ist, ob Datum und Zeit in einer gemeinsamen oder in zwei separaten Dimensionen modelliert werden sollen. Im Folgenden werden beide Möglichkeiten aufgezeigt.

Modellierung von Datum und Uhrzeit in getrennten Dimensionen

Zunächst soll der Ansatz mit zwei Dimensionen erläutert werden. Dabei hat man eine ganz normale Periode-Dimension, wie sie standardmäßig von DeltaMaster Modeler angelegt wird, mit den Ebenen Jahr – Quartal – Monat – Tag und eine Zeit-Dimension mit der Ebene Stunde.

Bericht Levels auf Periode- und Zeit-Dimension gefiltert

Abbildung 1: Bericht Levels auf Periode- und Zeit-Dimension gefiltert

Die Periode-Dimension bleibt unverändert zum DeltaMaster Modeler Standard. Für die Zeit-Dimension wird eine eigene View V_Import_DIM_Zeit erstellt, die auf alle Daten der Tabelle T_S_Schicht (vgl. Tabelle 2) zugreift. Zunächst wird hier allerdings nur eine Ebene angelegt, die die Stunden abbildet. Die Schichten werden noch nicht berücksichtigt.
Der Dimension werden noch die folgenden Attribute zugewiesen, wobei SchichtBEZ eine Attributbeziehung zu SchichtID erhält.

Attribute der Dimension Zeit

Abbildung 2: Attribute der Dimension Zeit

Jetzt wird eine zusätzliche Hierarchie Schichtzeit für die Zeit-Dimension angelegt, die die Level Schicht und Stunde abbildet.

Level der zusätzlichen Hierarchie Schichtzeit

Abbildung 3: Level der zusätzlichen Hierarchie Schichtzeit

Zusätzlich wird eine role playing dimension Arbeitstage für die Dimension Periode angelegt.

Role playing dimension Arbeitstage

Abbildung 4: Role playing dimension Arbeitstage

Damit diese Logik in einer Measuregroup Maschinenstörungen genutzt werden kann, wird nun eine View V_Import_FACT_Maschinenstörungen benötigt, die wie folgt aufgebaut ist:


CREATE VIEW [dbo].[V_Import_FACT_Maschinenstörungen] AS
	SELECT
		-- Dims
		CONVERT(
			SMALLDATETIME 
			, CAST(dbo.F_BC_DateID('dd', st.PeriodeID, 0) AS VARCHAR)
			, 112
		) AS Periode
		, DATEADD(
			dd
			, sch.Offset
			, CONVERT(
				SMALLDATETIME 
				, CAST(dbo.F_BC_DateID('dd', st.PeriodeID, 0) AS VARCHAR)
				, 112
			)
		) AS PeriodeSchicht
		, DATEPART(hh, st.PeriodeID) AS StundeID
		, st.MaschineID AS MaschineID
		-- Msrs
		, 1 AS Counter
	FROM dbo.Störungen st
	LEFT JOIN T_S_Schicht sch 
		ON sch.StundeID = DATEPART(hh, st.PeriodeID)

Entscheidend ist der gelb markierte Bereich. Hier wird der Arbeitstag als weiterer Datumswert errechnet. Zusätzlich wird die Stunde separat als Spalte StundeID aufgenommen.
An die Measuregroup werden die folgenden Dimensionen angebunden, die auf folgende Spalten aus V_Import_FACT_Maschinenstörungen zugreifen.

Dimension der Measuregroup Maschinenstörungen

Abbildung 5: Dimension der Measuregroup Maschinenstörungen

Als Measure für Maschinenstörungen dient ein einfacher Störungsmeldungszähler.
Im DeltaMaster werden jetzt separate Periodendimensionen für das Arbeitstagdatum und das tatsächliche Datum angezeigt. Um das System benutzerfreundlicher zu machen, eignet sich jetzt der Ansatz, der im Blogbeitrag „Verbreitere die Daten“ vom 02.05.2014 erläutert wurde. Die dafür nötige Schalterdimension nennen wir Datumssicht. Mit ihr kann man zwischen dem Arbeitstag Datum und dem tatsächlichen Datum umschalten. Jetzt gibt es nur noch eine Periodendimension.
Im Cubeskript muss folgender Scope eingefügt werden.

Dabei ist [Datumssicht].[Datumssicht].[Zeitbezug].&[2] das Arbeitstag-Datum und [Datumssicht].[Datumssicht].[Zeitbezug].&[1] das tatsächliche Datum. Jetzt kann im DeltaMaster ein Bericht erstellt werden, der automatisch, je nach Auswahl in der Schalterdimension, zwischen den Perioden und Zeitdimensionen umschaltet.

Ergebnis für Arbeitstag Datum

Abbildung 6: Ergebnis für Arbeitstag Datum

Ist in der Schalterdimension das Arbeitstag-Datum gewählt, so werden die Schichten an den jeweiligen Arbeitstagen angezeigt.

Bericht für Tatsächliches Datum

Abbildung 7: Bericht für Tatsächliches Datum

Ist das tatsächliche Datum gewählt, so wird dieses in Kombination mit der jeweiligen Stunde angezeigt. Um automatisch zwischen den beiden Zeithierarchien dynamisch im Bericht umschalten zu können, ist folgendes kleine MDX-Statement in die Achsendefinition einzubauen:


IIF(
	[Datumssicht].[Datumssicht].CurrentMember 
IS 
[Datumssicht].[Datumssicht].[Zeitbezug].&[2]
	,[Zeit].[Schichtzeit].[Schicht].Members
	,[Zeit].[Zeit].[Stunde].Members
)

Diese Maßnahmen sind sinnvoll, da bei falscher Kombination der Hierarchien aus den beiden Dimensionen falsche Ergebnisse auftreten können (z. B. tatsächliches Datum in Kombination mit der Schicht). Um dafür zu sorgen, dass auch tatsächlich die Bezeichnung der Schicht und der Uhrzeit angezeigt wird und nicht nur die ID, ist in DeltaMaster Modeler im Bericht Levels für das Level Stunde der Dimension Zeit die Name usage Eigenschaft auf Name zu stellen.

Einstellung der Name usage Eigenschaft

Abbildung 8: Einstellung der Name usage Eigenschaft

Für das Attribut SchichtID muss dieser Schritt in DataTools erfolgen. Dafür muss in den Attributeigenschaften unter NameColumn, die Souce der ColumnID auf die Spalte, in der die Bezeichnung zu finden ist, geändert werden.

Einstellung der Name usage Eigenschaft in DataTools

Abbildung 9: Einstellung der Name usage Eigenschaft in DataTools

Modellierung von Datum und Uhrzeit in einer gemeinsamen Dimension

Bei diesem Ansatz soll nur eine gemeinsame Dimension mit diversen Hierarchien und Display Foldern genutzt werden. Dafür wird zunächst im DeltaMaster Modeler Bericht Levels die Periode-Dimension um das Level PeriodeStunde erweitert. Diese Ebene wird jedoch auf unsichtbar gesetzt, da die Stunden in einer separaten Hierarchie mit eigenem display folder modelliert werden sollen, um die Möglichkeit der Kreuztabellierung zu erhalten.

Zusätzliches unsichtbares Level PeriodeStunde

Abbildung 10: Zusätzliches unsichtbares Level PeriodeStunde

Als Quelle der Dimension wird die View V_Import_DIM_PeriodeSchicht genutzt.


CREATE VIEW [dbo].[V_Import_DIM_PeriodeSchicht] AS
SELECT 
	DATEADD(HOUR, s.StundeID, p.[Periode])	Periode

	, DATEADD(
		DAY
		, s.Offset
		, DATEADD(HOUR, s.StundeID, p.[Periode])
	) AS PeriodeSchicht

	, s.SchichtID SchichtID
	, s.SchichtBEZ
	, s.StundeID
	, s.StundeBEZ
FROM [Schichtbetrieb].[dbo].[T_S_Periode] p
LEFT JOIN dbo.T_S_Schicht s
	ON 1 = 1

Diese liefert das tatsächliche Datum inklusive Stunde, das Datum des Arbeitstages mit Stunde (gelb markiert), sowie ID und Bezeichnung von Schicht und Stunde.
Im DeltaMaster Modeler müssen jetzt zahlreiche Attribute an die auf unsichtbar gestellte Ebene PeriodeStunde angehängt werden, wobei mit den Funktionen F_BC_DateID und F_BC_DateCODE in Verbindung mit dem PeriodeSchicht Datum gearbeitet wird:

Benötigte Attribute mit ihren Quellen

Abbildung 11: Benötigte Attribute mit ihren Quellen

Sämtliche BEZ-Attribute werden im Bericht Level attributes mit den jeweiligen ID-Attributen verbunden.
Bei diesem Ansatz werden nun gleich drei additional hierarchies benötigt: Arbeitstag, Uhrzeit und Schichtzeit. Arbeitstag bekommt den display folder der Hierarchie Periode. Die anderen beiden werden jeweils in einem eigenen display folder angelegt. Folgende Levels werden benötigt:

Level der zusätzlichen Hierarchien

Abbildung 12: Level der zusätzlichen Hierarchien

Im Gegensatz zum ersten Ansatz kann die FACT-View V_Import_FACT_Maschinenstörungen jetzt sehr einfach gehalten werden. Es reicht hier, den Zeitstempel des tatsächlichen Ereignisses (auf Stundenebene) anzugeben.


CREATE VIEW [dbo].[V_Import_FACT_Maschinenstörungen] AS
	SELECT
		-- Dims
		DATEADD(
			MINUTE
			, -DATEPART(MINUTE, st.PeriodeID)
			, st.PeriodeID
		) AS Periode		
		, st.MaschineID AS MaschineID
		-- Msrs
		, 1 AS Counter
	FROM dbo.Störungen st
	LEFT JOIN T_S_Schicht sch 
		ON sch.StundeID = DATEPART(hh, st.PeriodeID)

Dementsprechend simpel ist die Modellierung der Measuregroup. Bezüglich der Periodenwerte muss lediglich die Hierarchie Periode auf Ebene PeriodeStunde angebunden werden. Als Kennzahl wird wiederum ein Störungszähler genutzt.

Bericht Meas.grp. dimension source columns

Abbildung 13: Bericht Meas.grp. dimension source columns

In DataTools können jetzt noch die Hierachien Uhrzeit und Schichtzeit in einen gemeinsamen display folder gelegt werden (diese Einstellung ist in DeltaMaster Modeler nicht möglich).

Änderung des display folders der Hierarchie Schichtzeit

Abbildung 14: Änderung des display folders der Hierarchie Schichtzeit

Jetzt können in DeltaMaster wie schon beim ersten Ansatz die korrekten Werte kreuztabelliert dargestellt werden.

Störfälle kreuztabelliert nach tatsächlichem Datum zur jeweiligen Stunde

Abbildung 15: Störfälle kreuztabelliert nach tatsächlichem Datum zur jeweiligen Stunde

Störfälle kreuztabelliert nach Arbeitstag und Schicht

Abbildung 16: Störfälle kreuztabelliert nach Arbeitstag und Schicht

Auch bei diesem Ansatz besteht das Risiko, dass durch falsche Kombination von Hierarchien aus der Periode-Dimension fehlerhafte Werte angezeigt werden. Es ist also wichtig einem Nutzer das grundsätzliche Problem dieses Beitrags klarzumachen.

Fazit

Ob nun die Modellierungsvariante mit einer gemeinsamen oder zwei getrennten Dimensionen für Datum und Zeit genutzt werden soll, lässt sich nicht klar sagen.
Der hauptsächliche Nachteil des Ansatzes alles in einer Dimension zu modellieren ist, dass die Daten der Periode-Dimension um das Vierundzwanzigfache anwachsen (Anzahl Tage * 24 Stunden). Der Vorteil ist, dass es pro Datensatz nur einen Zeitstempel gibt, aus dem sich alles weitere ableiten lässt. Entsprechend wenige Anpassungen müssen in den Fact-Views vorgenommen werden. Dies wirkt sich auch positiv auf die Spaltenzahl der Fact-Tables aus.
Vorteil des Ansatzes der getrennten Dimensionen ist, dass mit role playing dimensions gearbeitet werden kann, die mithilfe einer Schalterdimension gewechselt werden können. Dies kann hilfreich sein, um das System nutzerfreundlicher zu machen und falscher Bedienung durch semantisch falsche Kombination von Datum und Uhrzeit ein Stück weit vorzubeugen (z. B. tatsächliches Datum mit Schichten).