October 24, 2017 at 8:19 pm
Ah... the fly in the ointment with the double pivot shown above is that it still returns NULLs for missing entries and row totals are still a pain.
--Jeff Moden
Change is inevitable... Change for the better is not.
November 30, 2017 at 10:43 pm
The other fly in the ointment is that it's also coming up with the wrong sums.
--Jeff Moden
Change is inevitable... Change for the better is not.
November 30, 2017 at 11:51 pm
david.leyden - Sunday, October 1, 2017 11:16 PMI've come across this article and a few others that suggest it is a limitation of PIVOT that you can't PIVOT more than one column. I am not sure I understand the need for creating two pivots and joining them. I would just alias the column we are pivoting on for each PIVOT clause.
SELECT [Company],
[Year],
[1_Qty]=MAX([1_Qty]),
[2_Qty]=MAX([2_Qty]),
[3_Qty]=MAX([3_Qty]),
[4_Qty]=MAX([4_Qty]),
[1_Amt]=MAX([1_Amt]),
[2_Amt]=MAX([2_Amt]),
[3_Amt]=MAX([3_Amt]),
[4_Amt]=MAX([4_Amt])
FROM
(
SELECT [Company],
Year,
[Qtr_Qty]=CONVERT( CHAR(1), Quarter)+'_Qty',
[Qtr_Amt]=CONVERT( CHAR(1), Quarter)+'_Amt',
[Quantity],
[Amount]
FROM @testtable
) [pt] PIVOT(SUM([Quantity]) FOR [Qtr_Qty] IN([1_Qty],
[2_Qty],
[3_Qty],
[4_Qty]))
AS [qty] PIVOT(SUM([Amount]) FOR [Qtr_Amt] IN([1_Amt],
[2_Amt],
[3_Amt],
[4_Amt]))
AS [amt]
GROUP BY [Company],
[Year];
If we run the million row data generator from the article...
--===== Create and populate a 1,000,000 row test table.
-- Column "RowNum" has a range of 1 to 1,000,000 unique numbers
-- Column "Company" has a range of "AAA" to "BBB" non-unique 3 character strings
-- Column "Amount has a range of 0.0000 to 9999.9900 non-unique numbers
-- Column "Quantity" has a range of 1 to 50,000 non-unique numbers
-- Column "Date" has a range of >=01/01/2000 and <01/01/2010 non-unique date/times
-- Columns Year and Quarter are the similarly named components of Date
-- Jeff Moden
It does, in fact, create a million rows...
SELECT COUNT(*) FROM #SomeTable3
If we take out the aggregation in the first SELECT and replace it with just a "*" and remove the GROUP BY, it should return a million rows...
SELECT *
--[COMPANY],
-- [YEAR],
-- [1_QTY]=MAX([1_QTY]),
-- [2_QTY]=MAX([2_QTY]),
-- [3_QTY]=MAX([3_QTY]),
-- [4_QTY]=MAX([4_QTY]),
-- [1_AMT]=MAX([1_AMT]),
-- [2_AMT]=MAX([2_AMT]),
-- [3_AMT]=MAX([3_AMT]),
-- [4_AMT]=MAX([4_AMT])
FROM
(
SELECT [Company],
Year,
[Qtr_Qty]=CONVERT( CHAR(1), Quarter)+'_Qty',
[Qtr_Amt]=CONVERT( CHAR(1), Quarter)+'_Amt',
[Quantity],
[Amount]
FROM #SomeTable3
(968031 rows affected)
Although I'm not sure that Microsoft supports your method of doing a multi-column pivot, it looks like the PIVOT operator cause a "break" and doesn't consider all of the rows. Either that, or the optimizer doesn't handle the way the column names were dynamically created.
Since it's also more complex than a CROSS TAB, I'll never even consider using PIVOT especially since we just proved this method "breaks" and produces the wrong answers because it ignores 10's of thousand of rows. And, yes, I checked. The derived table in the FROM clause produces a million rows and even when saving that as a Temp Table and using that Temp Table in place of the derived table, you still end up with the missing rows and the wrong answers.
p.s. I also understand why you used MAX but since the PIVOT is also NOT doing an actual PIVOT on this, you need to use a SUM but it still doesn't come up with the correct answer because it's still missing rows.
--Jeff Moden
Change is inevitable... Change for the better is not.
December 1, 2017 at 12:48 am
Ok... now I'm sure. If you run the code to generate the test table as we did above and then run the code below, you'll see what I mean. Details are in the comments.
--===== This is a single column pivot and it works just fine (for a PIVOT).
-- It produces the expected 80 rows from a million.
SELECT Company
,YEAR
,Q1Amt = amt.[1]
,Q2Amt = amt.[2]
,Q3Amt = amt.[3]
,Q4Amt = amt.[4]
FROM (SELECT Company,[Year],[Quarter],Amount FROM #SomeTable3) AS src
PIVOT (SUM(Amount) FOR [Quarter] IN ([1],[2],[3],[4])
) amt
ORDER BY Company, Year
;
--===== This demonstrates that you can't have more in the src query than what the PIVOT will use
-- which also means that you MUST have a source query for each column to be pivoted.
-- All we did was add the Quantity column to the "src" aliased derived table and Pivot no
-- longer works correctly. Try it and see. And check out the row count.
SELECT Company
,YEAR
,Q1Amt = amt.[1]
,Q2Amt = amt.[2]
,Q3Amt = amt.[3]
,Q4Amt = amt.[4]
FROM (SELECT Company,[Year],[Quarter],Amount,Quantity FROM #SomeTable3) AS src
PIVOT (SUM(Amount) FOR [Quarter] IN ([1],[2],[3],[4])
) amt
ORDER BY Company, Year
;
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 4 posts - 241 through 243 (of 243 total)
You must be logged in to reply to this topic. Login to reply