{"id":185,"date":"2007-08-15T13:00:00","date_gmt":"2007-08-15T13:00:00","guid":{"rendered":"\/lisa\/post\/2007\/08\/15\/Matrix-Rebuilt-More-non-standard-fun-with-T-SQL.aspx"},"modified":"2007-08-15T13:00:00","modified_gmt":"2007-08-15T13:00:00","slug":"matrix-rebuilt-more-non-standard-fun-with-t-sql","status":"publish","type":"post","link":"https:\/\/spacefold.com\/lisa\/2007\/08\/15\/matrix-rebuilt-more-non-standard-fun-with-t-sql\/","title":{"rendered":"Matrix Rebuilt: More non-standard fun with T-SQL"},"content":{"rendered":"<p>\nI don&#39;t know about you but I&#39;m not in love with the Matrix control in SQL RS.\n<\/p>\n<p>\nI&#39;m not in love with pivot tables in Excel, either, maybe it&#39;s me, I don&#39;t get my head around these constructs very well in general.&nbsp; <a href=\"http:\/\/www.sqlskills.com\/blogs\/liz\/2006\/07\/21\/ReportingServicesGettingTheMatrixToDisplayTwoSubtotalsForTheSameGroup\/\" title=\"Elizabeth Vitt makes the matrix sit up and beg\">Other people manage<\/a>. But, in RS, I just seem to spend too much time getting around the expectations of how things are supposed to work, which should make things easier but don&#39;t.&nbsp;\n<\/p>\n<p>\n(RANT-ASIDE: How many times have you seen a question about how to get subtotals before rather than after the rest of the columns, by the way?&nbsp; Who thought up that green triangle?&nbsp; It&#39;s a crowded interface, it&#39;s really hard to get all that functionality in, but <strong>still<\/strong>. OK, OK, I know it&#39;s easy to Monday-morning quarterback this stuff to death &#8212; I&#39;ve been on the other side, it&#39;s maddening. So I&#39;m not really complaining, and this rant does not constitute a fair criticism.)\n<\/p>\n<p>\nSo I like to do stuff in a table, where possible, even when I have to do a lot more work in T-SQL to get where the matrix would auto-magically put me.\n<\/p>\n<p>\nAs a result, even though I don&#39;t like pivot tables in Excel, I&#39;m kind of falling in love with <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/ms177410\/\" title=\"Using PIVOT and UNPIVOT in BOL\">the PIVOT clause<\/a> in SQL 2005. Like <a href=\"\/lisa\/2007\/08\/13\/Partition-Magic\/\" title=\"Partition magic\">the PARTITION stuff I&#39;ve already discussed<\/a>, this one really opens up (you should pardon the expression) reporting vistas.\n<\/p>\n<p>\nThis puppy gives you the ability to rotate tables.&nbsp; I figure that the matrix is actually using it, or something very similar to it with one exception which I&#39;ll discuss below, under the covers.&nbsp; So why not do it yourself?\n<\/p>\n<p>\nThe critical difference is dynamic expression of the columns you want.&nbsp; You&#39;ve got to express your pivoted columns &#8212; twice, actually &#8212; within your SELECT statement.&nbsp; Here is a an example PIVOT query <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/ms177634\/\" title=\"FROM Transact-SQL clause docs in MSDN\">from the docs<\/a>:\n<\/p>\n<p class=\"code\">\nUSE AdventureWorks<br \/>\nGO<br \/>\nSELECT VendorID, [164] AS Emp1, [198] AS Emp2, [223] AS Emp3, [231] AS Emp4, [233] AS Emp5<br \/>\nFROM <br \/>\n(SELECT PurchaseOrderID, EmployeeID, VendorID<br \/>\nFROM Purchasing.PurchaseOrderHeader) p<br \/>\n<font color=\"#ffffff\" style=\"background-color: #3399ff\">PIVOT<\/font><br \/>\n(<br \/>\nCOUNT (PurchaseOrderID)<br \/>\nFOR EmployeeID IN<br \/>\n( [164], [198], [223], [231], [233] )<br \/>\n) AS pvt<br \/>\nORDER BY VendorID;\n<\/p>\n<p>\nHow can you do that when you don&#39;t know what the columns are?\n<\/p>\n<p>\nI wrote a quick example of how to do this in T-SQL for a co-worker, unrelated to reporting.&nbsp; It&#39;s actually easier to do if you write the query as SQL using VB, where there are much more capable string-handling expressions than what I&#39;m going to show you here.\n<\/p>\n<p>\nFirst you need to have some way to determine your max number of columns. In this example, I&#39;ll be setting up my buckets by month values in a datetime column, and&nbsp;using DATEDIFF() from a specified date to express the meaning of each bucket (literally &quot;how many months ago did something happen&quot;). So I&#39;ll use DATEDIFF() in a similar but much quicker query, to figure how many buckets I have, first.\n<\/p>\n<p style=\"margin: 0in 0in 0pt\" class=\"code\">\n<span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">SET<\/span><span style=\"font-size: 10pt; font-family: 'Courier New'\"> <span style=\"color: blue\">NOCOUNT<\/span> <span style=\"color: blue\">ON<br \/>\nDECLARE<\/span> @Today <span style=\"color: blue\">AS<\/span> <span style=\"color: blue\">DATETIME<br \/>\nSET<\/span> @Today <span style=\"color: gray\">=<\/span> <span style=\"color: fuchsia\">GETDATE<\/span><span style=\"color: gray\">()<br \/>\n<\/span><span style=\"color: blue\">DECLARE<\/span> @TotalCols <span style=\"color: blue\">AS<\/span> <span style=\"color: blue\">INTEGER<\/span><\/span><span style=\"font-size: 10pt; color: blue\"><br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">DECLARE<\/span><span style=\"font-size: 10pt; font-family: 'Courier New'\"> @ColName <span style=\"color: blue\">AS<\/span> <span style=\"color: blue\">NVARCHAR<\/span><span style=\"color: gray\">(<\/span>50<span style=\"color: gray\">)<\/span><\/span> <br \/>\n<span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">DECLARE<\/span><span style=\"font-size: 10pt; font-family: 'Courier New'\"> @Statement1 <span style=\"color: blue\">AS<\/span> <span style=\"color: blue\">NVARCHAR<\/span><span style=\"color: gray\">(<\/span>2000<span style=\"color: gray\">),<\/span> <br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Statement2 <span style=\"color: blue\">AS<\/span> <span style=\"color: blue\">NVARCHAR<\/span><span style=\"color: gray\">(<\/span>2000<span style=\"color: gray\">)<\/span><\/span> <br \/>\n<span style=\"font-size: 10pt; color: green; font-family: 'Courier New'\">\/* do a query to find out your max number of colums *\/<\/span> <br \/>\n<span style=\"font-size: 10pt; color: green; font-family: 'Courier New'\">\/* You could do this differently if you don&#39;t always want<br \/>\n&nbsp;&nbsp; all the data.<br \/>\n*\/<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">SELECT<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @TotalCols <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <br \/>\n<\/span><span style=\"font-size: 10pt; color: fuchsia; font-family: 'Courier New'\">&nbsp;&nbsp; COUNT<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">(<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">DISTINCT<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: fuchsia; font-family: 'Courier New'\">DATEDIFF<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">(<\/span><span style=\"font-size: 10pt; color: fuchsia; font-family: 'Courier New'\">month<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">,E<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\">ventDate<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">,<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\">@Today<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">))<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">&nbsp;&nbsp; FROM<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> EventTable<\/span>\n<\/p>\n<p>\nNext, you need to set up the two clauses that reference those columns.&nbsp; You&#39;ll need a second variable (besides the total number of columns) that indicates some base column name that is meaningful within your data set, to which you will add an index or identifier.\n<\/p>\n<div class=\"code\">\n<span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"><\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"><\/p>\n<p style=\"margin: 0in 0in 0pt\">\n<span style=\"font-size: 10pt; color: green; font-family: 'Courier New'\">\/* decide how you&nbsp;want to&nbsp;name the cols&nbsp;<br \/>\n&nbsp;&nbsp; in this specific query *\/<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @ColName <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;MonthsAgoGrp&#39;<\/span>\n<\/p>\n<p><\/span>\n<\/div>\n<p style=\"margin: 0in 0in 0pt\">\n&nbsp;\n<\/p>\n<p style=\"margin: 0in 0in 0pt\">\nNow you can derive the two clauses you need.&nbsp; This part is completely generic (and again it is much, much easier to write it in VB than in T-SQL although this should be reasonably clear).&nbsp; You can move it into appropriate generic functions in either&nbsp;.NET code&nbsp;or T-SQL, passing in @ColName and @TotalCols, for any PIVOT-y query you wanted to assemble:\n<\/p>\n<p class=\"code\">\n<span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">DECLARE<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @ThisItem <\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">AS<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">INTEGER<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">,<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @ThisPos <\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">AS<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">INTEGER<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">,<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\">&nbsp;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @sThisItem <\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">AS<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">NVARCHAR<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">(<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\">10<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">)<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;[0] AS [&#39;<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @ColName <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;0]&#39;<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement2 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;[0]&#39;<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @ThisItem <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> 1<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">WHILE<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @ThisItem <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">&lt;<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @TotalCols <br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">&nbsp;&nbsp; BEGIN<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @sThisItem <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: fuchsia; font-family: 'Courier New'\">CAST<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">(<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\">@ThisItem <\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">AS<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">NVARCHAR<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">)<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;,[&#39;<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @sThisItem <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;] AS [&#39;<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @ColName <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @sThisItem <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;]&#39;<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement2 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement2 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;,[&#39;<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @sThisItem <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;]&#39;<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @ThisItem <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @ThisItem <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> 1<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">&nbsp;&nbsp; END<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><br \/>\n<span style=\"font-size: 10pt; color: green; font-family: 'Courier New'\">\/* You can print out @Statement1 and @Statement2 at this point,<br \/>\n&nbsp;&nbsp; and verify that they are in fact the two clauses in the PIVOT<br \/>\n&nbsp;&nbsp; statement that we needed to create differently for different<br \/>\n&nbsp;&nbsp; numbers of columns<br \/>\n*\/<\/span>\n<\/p>\n<p>\nNow&nbsp;you&#39;ve got what you need to assemble the query and execute it:&nbsp;\n<\/p>\n<p class=\"code\">\n<span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <br \/>\n&nbsp;&nbsp; N<\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39; SELECT EventType, &#39;<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <br \/>\n&nbsp;&nbsp; N<\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39; FROM &#39;<br \/>\n<\/span><span style=\"font-size: 10pt; color: green; font-family: 'Courier New'\">\/* your pivot-able query here: *\/<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">&nbsp;SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <br \/>\n&nbsp;&nbsp; N<\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;(SELECT EventType,<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DATEDIFF(month,EventDate,&#39;&#39;&#39;<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <br \/>\n<\/span><span style=\"font-size: 10pt; color: fuchsia; font-family: 'Courier New'\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CAST<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">(<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\">@Today <\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">AS<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">NVARCHAR<\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">)<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<br \/>\n<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\">&nbsp;&nbsp; N<\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;&#39;&#39;) AS MonthsAgo,&nbsp;EventID&nbsp;<br \/>\n&nbsp;&nbsp; FROM&nbsp;EventTable ) SourceTable &#39;<br \/>\n<\/span><span style=\"font-size: 10pt; color: green; font-family: 'Arial','sans-serif'\"><br \/>\n<\/span><span style=\"font-size: 10pt; color: green; font-family: 'Courier New'\">\/* add the pivot aggregation function of your choice *\/<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<br \/>\n<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\">&nbsp;&nbsp; N<\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39; PIVOT &#39;<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <br \/>\n&nbsp;&nbsp; N<\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;(COUNT(EventID) FOR MonthsAgo IN (&#39;<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\">&nbsp;<br \/>\n<\/span><span style=\"font-size: 10pt; color: green; font-family: 'Arial','sans-serif'\"><br \/>\n<\/span><span style=\"font-size: 10pt; color: green; font-family: 'Courier New'\">\/* our second generated clause here *\/<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> <br \/>\n&nbsp;&nbsp; @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement2 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> N<\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;)) AS PivotTable &#39;<\/p>\n<p><\/span><span style=\"font-size: 10pt; color: green; font-family: 'Courier New'\">\/* order the results if desired *\/<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> N<\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39; ORDER BY&nbsp;EventType &#39;<\/p>\n<p><\/span><span style=\"font-size: 10pt; color: green; font-family: 'Courier New'\">\/* end the statement&nbsp; and execute it *\/<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">SET<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">=<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1 <\/span><span style=\"font-size: 10pt; color: gray; font-family: 'Courier New'\">+<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> N<\/span><span style=\"font-size: 10pt; color: red; font-family: 'Courier New'\">&#39;;&#39;<br \/>\n<\/span><span style=\"font-size: 10pt; color: blue; font-family: 'Courier New'\">EXEC<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\">&nbsp;<\/span><span style=\"font-size: 10pt; color: maroon; font-family: 'Courier New'\">sp_executeSQL<\/span><span style=\"font-size: 10pt; color: black; font-family: 'Courier New'\"> @Statement1<\/span>\n<\/p>\n<p>\nYour&nbsp;generated query&nbsp;for this example, the thing that executed, looked something like this (assuming @TotalCols = 5):\n<\/p>\n<p class=\"code\">\nSELECT EventType,<br \/>\n&nbsp;&nbsp; [0] AS MonthsAgoGrp0, [1] AS MonthsAgoGrp1, <br \/>\n&nbsp;&nbsp; [2] AS MonthsAgoGrp2,&nbsp;[3] AS MonthsAgoGrp3, [4] AS MonthsAgoGrp4<br \/>\nFROM<br \/>\n(SELECT&nbsp; EventType,<br \/>\n&nbsp;&nbsp; DATEDIFF(month,EventDate,&#39;8\/17\/2007&#39;)&nbsp; AS MonthsAgo, EventID<br \/>\n&nbsp; FROM&nbsp;EventTable )&nbsp; SourceTable<br \/>\nPIVOT<br \/>\n(<br \/>\n&nbsp; COUNT(EventID)<br \/>\n&nbsp; FOR MonthsAgo IN&nbsp;<br \/>\n&nbsp; ([0],[1],[2],[3],[4])<br \/>\n) AS PivotTable<br \/>\nORDER BY EventType ;\n<\/p>\n<p>\n&nbsp;\n<\/p>\n<p>\nI figure that, underneath, the matrix has to be processing the data something like this; first figuring&nbsp;out the buckets and then designing either a PIVOT clause or something similar, with its dynamically-created column instructions,&nbsp;to&nbsp;execute on the data set with which you present it in the report.&nbsp;\n<\/p>\n<p>\nNow you know that, for reporting purposes, this isn&#39;t the end of the story &#8212; although it solves my co-worker&#39;s problem pretty neatly. You still have to tell the report about your dynamic structures, and where you have buckets that can&#39;t be indexed as easily as &quot;months ago&quot;, you have to provide an index value to them somehow (this is another place where you will find ROW_NUMBER() and PARTITION helpful).\n<\/p>\n<p>\nBut that&#39;s enough for now, and I hope it gives you some ideas&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I don&#39;t know about you but I&#39;m not in love with the Matrix control in SQL RS. I&#39;m not in love with pivot tables in Excel, either, maybe it&#39;s me, I don&#39;t get my head around these constructs very well in general.&nbsp; Other people manage. But, in RS, I just seem to spend too much<a class=\"more-link\" href=\"https:\/\/spacefold.com\/lisa\/2007\/08\/15\/matrix-rebuilt-more-non-standard-fun-with-t-sql\/\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,6],"tags":[],"class_list":["post-185","post","type-post","status-publish","format-standard","hentry","category-reporting","category-sql-server"],"_links":{"self":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts\/185","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/comments?post=185"}],"version-history":[{"count":0,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts\/185\/revisions"}],"wp:attachment":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/media?parent=185"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/categories?post=185"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/tags?post=185"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}