{"id":289,"date":"2015-01-24T14:11:23","date_gmt":"2015-01-24T13:11:23","guid":{"rendered":"http:\/\/www.csopro.de\/biblog\/?p=289"},"modified":"2015-01-24T14:13:13","modified_gmt":"2015-01-24T13:13:13","slug":"ssas-tabular-dax-datediff-ersatz","status":"publish","type":"post","link":"https:\/\/www.csopro.de\/biblog\/2015\/01\/ssas-tabular-dax-datediff-ersatz\/","title":{"rendered":"SSAS Tabular DAX: DATEDIFF-Ersatz"},"content":{"rendered":"<p>In (tabular) Cubes m\u00f6chte man m\u00f6glicherweise Berechnungen durchf\u00fchren, bei denen die Anzahl der Tage zwischen zwei Datumswerten ermittelt werden sollen.<\/p>\n<p>\u00dcberraschender Weise gibt es keine DateDiff-Funktion in DAX.<\/p>\n<p>Zwar kursieren im Web einige Beispiele f\u00fcr einen Ersatz, allerdings gefallen sie mir nicht.<\/p>\n<h2>Hintergrundwissen<\/h2>\n<p>Deswegen schauen wir uns zun\u00e4chst n\u00e4her an, wie in (tabular) Cubes Datumswerte gespeichert werden:<\/p>\n<p>Datumswerte werden intern als Zahlen gespeichert, wobei der ganzzahlige Anteil die Anzahl der Tage seit 30.12.1899 angibt und der Nachkommaanteil die Uhrzeit.<\/p>\n<p>Wir k\u00f6nnen das ganz leicht im Cube sehen, indem wir ein Datum mit 1.0 (deutsch 1,0) multiplizieren (im DAX reicht *1. bzw. *1, \u2013 je nachdem welche Lokalisierung eingestellt ist ) \u2013 oder \u00fcber value(\u2026) in eine Zahl konvertieren.<\/p>\n<p>Ich habe einen kleinen Cube erstellt \u2013 mit folgender Datenquelle:<\/p>\n<blockquote>\n<p>select convert(datetime, &#8218;17.8.2011 17:53:12&#8216;, 104) as DatumUhrzeit, convert(date, &#8218;17.8.2011&#8216;, 104) as Datum<br \/>UNION ALL<br \/>select convert(datetime, &#8218;1.3.2000 06:13:27&#8216;, 104), convert(date, &#8218;1.3.2000&#8216;, 104)<br \/>UNION ALL<br \/>select convert(datetime, &#8218;5.3.2000 01:13:27&#8216;, 104), convert(date, &#8218;5.3.2000&#8216;, 104)<br \/>UNION ALL<br \/>select convert(datetime, &#8218;1.1.1900 5:30:00&#8216;, 104), convert(date, &#8218;1.1.1900&#8216;, 104)<br \/>UNION ALL<br \/>select convert(datetime, &#8218;31.12.1899 17:30:00&#8216;, 104), convert(date, &#8218;31.12.1899&#8216;, 104)<br \/>UNION ALL<br \/>select convert(datetime, &#8218;27.12.2014 20:22:55&#8216;, 104), convert(date, &#8218;27.12.2014&#8216;, 104)<br \/>UNION ALL<br \/>select getdate(), convert(date, getdate())<\/p>\n<\/blockquote>\n<p>Dann habe ich jeweils eine berechnete Spalte \u2013 wie oben beschrieben \u2013 hinzugef\u00fcgt. Das Ergebnis:<\/p>\n<p><a href=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2015\/01\/image5.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2015\/01\/image_thumb5.png\" width=\"644\" height=\"222\"><\/a><\/p>\n<h2>DateDiff von Dates<\/h2>\n<p>Um nun die Differenz zwischen 2 Date-Spalten zu ermitteln, muss man sie nur voneinander abziehen. Das Ergebnis hat allerdings den Datentyp DateTime, weswegen man das Ergebnis noch in ein int verwandeln muss:<\/p>\n<blockquote>\n<p>([Datum2] \u2013[Datum1]) * 1<\/p>\n<\/blockquote>\n<p>oder<\/p>\n<blockquote>\n<p>int([Datum2]-[Datum1])<\/p>\n<\/blockquote>\n<p>Um das zu demonstrieren, habe ich meine Quelle angepasst und das Ergebnis sieht so aus:<\/p>\n<p><a href=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2015\/01\/image3.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2015\/01\/image_thumb3.png\" width=\"644\" height=\"308\"><\/a><\/p>\n<h2>DateDiff von DateTimes<\/h2>\n<p>Wenn wir aber 2 DateTimes haben, d\u00fcrfen wir sie nicht einfach voneinander abziehen (also int([DatumUhrzeit2]-[DatumUhrzeit1])), da die Uhrzeiten keine rolle spielen sollen. Stattdessen m\u00fcssen wir die Datumswerte zun\u00e4chst nach int konvertieren (dabei rundet DAX immer ab) und dann subtrahieren:<\/p>\n<blockquote>\n<p>int([DatumUhrzeit2])-int([DatumUhrzeit1])<\/p>\n<\/blockquote>\n<p><a href=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2015\/01\/image6.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2015\/01\/image_thumb6.png\" width=\"644\" height=\"230\"><\/a><\/p>\n<p>Wir sehen, dass die falsche Methode immer dann einen zu niedrigen Wert ausweist, wenn das abgezogene Datum eine gr\u00f6\u00dfere Uhrzeit als der Minuend aufweist.<\/p>\n<h2><\/h2>\n<h2>Erweiterungen: Alter<\/h2>\n<p>Falls mein ein Alter bis heute berechnen will, kann man das mit der gleichen Logik machen. Die DAX-Funktionen sind:<\/p>\n<ul>\n<li>now() liefert das heutige Datum inkl. aktueller Uhrzeit<\/li>\n<li>today() liefert nur das heutige Datum<\/li>\n<\/ul>\n<p>Diese Funktionen werden im \u00fcbrigen beim Process aufgerufen und nicht beim Auswerten in einem Frontend-Programm<\/p>\n<h2><\/h2>\n<h2>Erweiterungen: DateDiff in Sekunden<\/h2>\n<p>Ganz analog kann man nat\u00fcrlich vorgehen, um die Differenz in anderen Einheiten auszurechen:<\/p>\n<p>Man multipliziert einfach die DateTime-Spalte mit dem entsprechenden Wert:<\/p>\n<ul>\n<li>* 24 f\u00fcr Stunden<\/li>\n<li>* 24 * 60 f\u00fcr Minuten<\/li>\n<li>* 24 * 60 * 60 f\u00fcr Sekunden<\/li>\n<\/ul>\n<p>und konvertiert dann die Zahl in ein int.<\/p>\n<p>Allerdings kann so eine Differenz in Monaten bzw. Jahren nicht berechnet werden. Das m\u00fcsste man zun\u00e4chst wohl definieren (Was bedeutet 17.1.2015 18:33 \u2013 18.3.2012 17:55 in Monaten?) und dann ggf. \u00fcber if-Statements selbst berechnen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In (tabular) Cubes m\u00f6chte man m\u00f6glicherweise Berechnungen durchf\u00fchren, bei denen die Anzahl der Tage zwischen zwei Datumswerten ermittelt werden sollen. \u00dcberraschender Weise gibt es keine DateDiff-Funktion in DAX. Zwar kursieren im Web einige Beispiele f\u00fcr einen Ersatz, allerdings gefallen sie mir nicht. Hintergrundwissen Deswegen schauen wir uns zun\u00e4chst n\u00e4her an, wie in (tabular) Cubes Datumswerte &hellip; <a href=\"https:\/\/www.csopro.de\/biblog\/2015\/01\/ssas-tabular-dax-datediff-ersatz\/\" class=\"more-link\"><span class=\"screen-reader-text\">SSAS Tabular DAX: DATEDIFF-Ersatz<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[29,28,23,31,30],"class_list":["post-289","post","type-post","status-publish","format-standard","hentry","category-analysisservices","tag-datediff","tag-dax","tag-tabular","tag-today","tag-value"],"_links":{"self":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/289","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/comments?post=289"}],"version-history":[{"count":2,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/289\/revisions"}],"predecessor-version":[{"id":295,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/289\/revisions\/295"}],"wp:attachment":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/media?parent=289"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/categories?post=289"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/tags?post=289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}