{"id":76,"date":"2010-07-19T15:53:41","date_gmt":"2010-07-19T13:53:41","guid":{"rendered":"http:\/\/www.capri-soft.de\/blog\/?p=76"},"modified":"2010-07-19T16:12:41","modified_gmt":"2010-07-19T14:12:41","slug":"ms-sql-server-tabelle-mit-pivot-drehen-z-b-fur-zeitreihenanalyse","status":"publish","type":"post","link":"https:\/\/www.capri-soft.de\/blog\/?p=76","title":{"rendered":"MS SQL Server-Tabelle mit Pivot drehen (z.B. f\u00fcr Zeitreihenanalyse)"},"content":{"rendered":"<h1>Problemfeldbeschreibung<\/h1>\n<p>Beim Arbeiten mit Daten im Microsoft SQL Server kommt man gelegentlich an den Punkt, an dem man sich das &#8222;Drehen&#8220; von Tabellendaten als n\u00fctzlich entpuppt. Anwendungsgebiete sind u.a. die Prognoserechnung, Zeitreihenanalyse oder einfach Matrizenmultiplikation. <\/p>\n<p>Nehmen wir z.B. den folgenden Datensatz, er soll gedreht werden:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n200901\u00a0\u00a0 \u00a0\u00a01\u00a0\u00a0 \u00a02009\u00a0\u00a0 \u00a00\u00a0\u00a0 \u00a030\r\n200902\u00a0\u00a0 \u00a0\u00a02\u00a0\u00a0 \u00a02009\u00a0\u00a0 \u00a058\u00a0\u00a0 \u00a016\r\n200903\u00a0\u00a0 \u00a0\u00a03\u00a0\u00a0 \u00a02009\u00a0\u00a0 \u00a0520\u00a0\u00a0 \u00a015\r\n200906\u00a0\u00a0 \u00a0\u00a06\u00a0\u00a0 \u00a02009\u00a0\u00a0 \u00a0780\u00a0\u00a0 \u00a015\r\n200809\u00a0\u00a0 \u00a0\u00a09\u00a0\u00a0 \u00a02008\u00a0\u00a0 \u00a00\u00a0\u00a0 \u00a07\r\n200909\u00a0\u00a0 \u00a0 9\u00a0\u00a0 \u00a02009\u00a0\u00a0 \u00a0260\u00a0\u00a0 \u00a08\r\n200810\u00a0\u00a0 \u00a010\u00a0\u00a0 \u00a02008\u00a0\u00a0 \u00a00\u00a0\u00a0 \u00a0\r\n<\/pre>\n<p>Der unerfahrene Datenbankentwickler beginnt dann h\u00e4ufig mit der Implementierung von langsamen Cursorskripten \u00e1 la<\/p>\n<p>DECLARE @compcode  varchar(255)<br \/>\nDECLARE @market  varchar(255)<br \/>\nDECLARE @salesdiv  varchar(255)<br \/>\nDECLARE @material  varchar(255)<br \/>\nDECLARE @month  int<br \/>\nDECLARE @year  int<br \/>\nDECLARE @bruttoumsatz  varchar(255)<br \/>\nDECLARE @amount varchar(255)<br \/>\nDECLARE @spalte varchar(255)<\/p>\n<p>DECLARE mmg_cursor CURSOR FOR<br \/>\nSELECT compcode, market, salesdiv, material, month, year, bruttoumsatz, amount<br \/>\nFROM cube WHERE CAST(CAST(year as varchar)+(CASE WHEN month<10 THEN \n         ('0'+CAST(month as varchar)) \n        ELSE CAST(@month as varchar) END ) as int) >=200610<\/p>\n<p>OPEN mmg_cursor<\/p>\n<p>FETCH NEXT FROM mmg_cursor INTO @compcode,@market, @salesdiv, @material,<br \/>\n                                                  @month, @year, @bruttoumsatz, @amount<\/p>\n<p>WHILE @@FETCH_STATUS = 0<br \/>\nBEGIN<\/p>\n<p>\tSET @spalte=CAST(@year as varchar)+(CASE WHEN @month<10 THEN\n               ('0'+CAST(@month as varchar)) \n               ELSE CAST(@month as varchar) END )\n\n\tEXEC('UPDATE hypercube SET ['+@spalte+']='+@amount+' \n                WHERE [compcode]='''+@compcode+''' AND [salesdiv]='''+@salesdiv+''' \n                AND [market]='''+@market+''' AND [material]='''+@material+''' ')\n\n    FETCH NEXT FROM mmg_cursor INTO @compcode,@market, @salesdiv, @material, \n                                       @month, @year, @bruttoumsatz, @amount\nEND\n\nDEALLOCATE mmg_cursor\n[\/javascript]\n\n\n\n<h1>Ansatz<\/h1>\n<p>Es bedarf keines Benchmarks oder einer Messung um festzustellen, dass diese Methode sehr zeitaufw\u00e4ndig und unzeitgem\u00e4\u00df ist. Microsoft r\u00e4t von solchen Cursor-Skripten ab und r\u00e4t von der Nutzung der PIVOT-Funktion, die an Performance und Handhabung kaum zu \u00fcberbieten ist.<\/p>\n<h1>L\u00f6sung<\/h1>\n<p>Das folgende SQL-Skript dreht die Tabelle mit PIVOT (Die MS SQL Server-Datenbank muss hierzu mind. auf MSSQL2005-Kompatibilit\u00e4t gestellt werden.<\/p>\n<p>declare @columns varchar(max)<br \/>\ndeclare @columnsoben varchar(max)<br \/>\ndeclare @count int<br \/>\ndeclare @max int<br \/>\ndeclare @current int<br \/>\ndeclare @sql nvarchar(max)<br \/>\ndeclare @t table(id int identity(1,1), datekey int)<br \/>\ninsert into @t select distinct datekey from vglobe2 order by 1<br \/>\nset @columns = &#8220;<br \/>\nset @columnsoben = &#8220;<br \/>\nset @count = 1<br \/>\nset @max = (select max(id) from @t)<br \/>\nwhile (@count <= @max)\nbegin\n\tset @current = (select datekey from @t where id = @count)\n\tset @columns = @columns +  '[' +  cast(@current as varchar(6)) +'], '\n\tset @columnsOben = @columnsOben +  '[' +  cast(@current as varchar(6)) +'],' +\n                                       '0 as [' +  cast(@current as varchar(6)) +'stat],'\n\tset @count = @count+1\nend\nset @columns = substring(@columns, 1, len(@columns)-1) -- letztes komma\nset @columnsOben = substring(@columnsOben, 1, len(@columnsOben)-1) -- letztes komma\nset @sql = 'SELECT Artikel, ' + @columnsoben +\n\t\t   N' FROM\n\t\t\t (SELECT artikel, bruttoumsatz , datekey FROM vglobe2) p\n\t\t\tPIVOT\n\t\t\t(\n\t\t\tsum(bruttoumsatz)\n\t\t\tFOR  datekey  in (' + @columns + N')\n\t\t\t\t) AS pvt\n\t\t\tORDER BY 1'\n\nprint @sql\nexec sp_executesql @sql\n\n[\/sql]\n<\/p>\n<iframe src=\"http:\/\/www.facebook.com\/plugins\/like.php?href=https%3A%2F%2Fwww.capri-soft.de%2Fblog%2F%3Fp%3D76&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light\" scrolling=\"no\" frameborder=\"0\" allowTransparency=\"true\" style=\"border:none; overflow:hidden; width:450px;margin-top:5px;\"><\/iframe>","protected":false},"excerpt":{"rendered":"<p>Problemfeldbeschreibung Beim Arbeiten mit Daten im Microsoft SQL Server kommt man gelegentlich an den Punkt, an dem man sich das &#8222;Drehen&#8220; von Tabellendaten als n\u00fctzlich entpuppt. Anwendungsgebiete sind u.a. die Prognoserechnung, Zeitreihenanalyse oder einfach Matrizenmultiplikation. Nehmen wir z.B. den folgenden Datensatz, er soll gedreht werden: 200901\u00a0\u00a0 \u00a0\u00a01\u00a0\u00a0 \u00a02009\u00a0\u00a0 \u00a00\u00a0\u00a0 \u00a030 200902\u00a0\u00a0 \u00a0\u00a02\u00a0\u00a0 \u00a02009\u00a0\u00a0 \u00a058\u00a0\u00a0 \u00a016 &hellip; <a href=\"https:\/\/www.capri-soft.de\/blog\/?p=76\" class=\"more-link\"><span class=\"screen-reader-text\">MS SQL Server-Tabelle mit Pivot drehen (z.B. f\u00fcr Zeitreihenanalyse)<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[11],"tags":[],"class_list":["post-76","post","type-post","status-publish","format-standard","hentry","category-ms-sql-server"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4yGeN-1e","jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/76","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=76"}],"version-history":[{"count":10,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/76\/revisions"}],"predecessor-version":[{"id":78,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/76\/revisions\/78"}],"wp:attachment":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=76"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=76"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=76"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}