Advertisement
Guest User

Dynamic Pivot Columns

a guest
Feb 9th, 2011
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
T-SQL 4.50 KB | None | 0 0
  1. CREATE TABLE PersonType
  2. (
  3.      [PersonTypeID] tinyint identity(1,1) primary key
  4.     ,[PersonTypeName] varchar(30) default('')
  5.     ,[Description] varchar(255) default('')
  6. )
  7. INSERT INTO PersonType([PersonTypeName], [Description])
  8. VALUES('Geek','A person with an unusual or odd personality');
  9. INSERT INTO PersonType([PersonTypeName], [Description])
  10. VALUES('Hipster','Someone who rejects the established culture; advocates extreme liberalism in politics and lifestyle');
  11. INSERT INTO PersonType([PersonTypeName], [Description])
  12. VALUES('Nerd','An intelligent but single-minded expert in a particular technical field or profession');
  13.  
  14.  
  15. CREATE TABLE Person
  16. (
  17.      [PersonID] int identity(1,1) Primary Key
  18.     ,[PersonTypeID] tinyint
  19.     ,[FirstName] varchar(50) default('')
  20.     ,[LastName] varchar(50) default('')
  21.     ,[Age]  AS (DATEDIFF(YEAR,[DateOfBirth],ISNULL([DateOfDeath],GETDATE()))) /* Too Lazy to calculate myself */
  22.     ,[DateOfBirth] date
  23.     ,[DateOfDeath] date
  24. )
  25. INSERT INTO Person(PersonTypeID, FirstName, LastName, DateOfBirth, DateOfDeath)
  26. VALUES (1, 'Steve','Wozniak','1950-08-11', NULL)
  27. INSERT INTO Person(PersonTypeID, FirstName, LastName, DateOfBirth, DateOfDeath)
  28. VALUES (1, 'William Henry','Gates','1955-10-28', NULL)
  29. INSERT INTO Person(PersonTypeID, FirstName, LastName, DateOfBirth, DateOfDeath)
  30. VALUES (1, 'Richard William','Wheaton','1972-07-29', NULL)
  31. INSERT INTO Person(PersonTypeID, FirstName, LastName, DateOfBirth, DateOfDeath)
  32. VALUES (2, 'Jerome John','Garcia','1942-08-01', '1995-08-05')
  33. INSERT INTO Person(PersonTypeID, FirstName, LastName, DateOfBirth, DateOfDeath)
  34. VALUES (2, 'Steven Paul','Jobs','1955-02-24', NULL)
  35. INSERT INTO Person(PersonTypeID, FirstName, LastName, DateOfBirth, DateOfDeath)
  36. VALUES (2, 'Evil Steven Paul','Jobs','1955-02-24', NULL)
  37. INSERT INTO Person(PersonTypeID, FirstName, LastName, DateOfBirth, DateOfDeath)
  38. VALUES (3, 'Albert','Einstein','1879-04-18', '1955-05-18')
  39. INSERT INTO Person(PersonTypeID, FirstName, LastName, DateOfBirth, DateOfDeath)
  40. VALUES (3, 'Michelangelo','Simoni','1475-03-06', '1564-02-18')
  41. INSERT INTO Person(PersonTypeID, FirstName, LastName, DateOfBirth, DateOfDeath)
  42. VALUES (3, 'Tina','Brown','1953-11-21', NULL)
  43. INSERT INTO Person(PersonTypeID, FirstName, LastName, DateOfBirth, DateOfDeath)
  44. VALUES (3, 'Elizabeth Stamatina','Fey','1970-05-18', NULL)
  45. INSERT INTO Person(PersonTypeID, FirstName, LastName, DateOfBirth, DateOfDeath)
  46. VALUES (3, 'Fake Sarah Palin','Fey','1970-05-18', NULL)
  47.  
  48.  
  49. /* Magic happens here.
  50. We use the SQL STUFF function (http://msdn.microsoft.com/en-us/library/ms188043.aspx)
  51. and the FOR XML clause (http://msdn.microsoft.com/en-us/library/ms190922.aspx)
  52. to select out our PersonTypeName's
  53.  
  54. Result: [Geek],[Hipster],[Nerd]
  55. */
  56. DECLARE @PersonTypeList VARCHAR(MAX);
  57. SELECT @PersonTypeList = STUFF((SELECT '],[' + PersonTypeName FROM PersonType FOR XML PATH('')),1,2,'') + ']'
  58.  
  59. /* Pivot Time
  60. Just a basic pivot here, we are getting the Age from Person, and then doing an inner join
  61. to PersonType and doing a Pivot on the PersonTypeName.
  62.  */
  63. DECLARE @sql VARCHAR(MAX)
  64. SET @sql =
  65. 'SELECT * FROM
  66. (SELECT p.[Age], pt.PersonTypeName, p.PersonID FROM Person p
  67. INNER JOIN PersonType pt on pt.PersonTypeID = p.PersonTypeID
  68. ) src
  69. PIVOT (COUNT(PersonID) FOR PersonTypeName IN ('+@PersonTypeList+')) as pvt
  70. ORDER BY [Age] ASC'
  71.  
  72. EXECUTE (@sql)
  73. /*
  74. Result:
  75. Age     Geek    Hipster Nerd
  76. 39      1       0       0
  77. 41      0       0       2
  78. 53      0       1       0
  79. 56      1       2       0
  80. 58      0       0       1
  81. 61      1       0       0
  82. 76      0       0       1
  83. 89      0       0       1
  84.        
  85. Cool you say, but I could of just coded those PersonType's into the sql and it would of done the same.
  86. Ok, but what about when we add a new PersonType ?
  87. */
  88. INSERT INTO PersonType([PersonTypeName], [Description])
  89. VALUES('Jock','A person trained to compete in sports');
  90. INSERT INTO Person(PersonTypeID, FirstName, LastName, DateOfBirth, DateOfDeath)
  91. VALUES (4, 'Michael Jeffrey','Jordan','1963-02-17', NULL)
  92.  
  93. /*
  94. Well lets see what happens
  95. */
  96. SELECT @PersonTypeList = STUFF((SELECT '],[' + PersonTypeName FROM PersonType FOR XML PATH('')),1,2,'') + ']'
  97. SET @sql =
  98. 'SELECT * FROM
  99. (SELECT p.[Age], pt.PersonTypeName, p.PersonID FROM Person p
  100. INNER JOIN PersonType pt on pt.PersonTypeID = p.PersonTypeID
  101. ) src
  102. PIVOT (COUNT(PersonID) FOR PersonTypeName IN ('+@PersonTypeList+')) as pvt
  103. ORDER BY [Age] ASC'
  104.  
  105. EXECUTE (@sql)
  106.  
  107. /*
  108. Result:
  109. Age Geek    Hipster Nerd    Jock
  110. 39  1       0       0       0
  111. 41  0       0       2       0
  112. 48  0       0       0       1
  113. 53  0       1       0       0
  114. 56  1       2       0       0
  115. 58  0       0       1       0
  116. 61  1       0       0       0
  117. 76  0       0       1       0
  118. 89  0       0       1       0
  119.  
  120. Holy shitballs batman, it is automatically getting the PersonTypes!
  121. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement