June 23, 2008 at 7:49 am
Heh... I wonder if the use of UNPIVOT constitutes cheating too much in this case?
Still, some awesome code... Thanks Jeff W and Peter. I really didn't think it could be done, but should know better especially with folks like the two of you... 🙂
--Jeff Moden
Change is inevitable... Change for the better is not.
June 23, 2008 at 8:01 am
Riding JW's solution...
--Peso 3
SELECTp.Company,
p.[Year],
COALESCE(p.Amt1, 0.0) As [Q1 Amt],
CAST(COALESCE(p.Qty1, 0) AS INT) As [Q1 Qty],
COALESCE(p.Amt2, 0.0) As [Q2 Amt],
CAST(COALESCE(p.Qty2, 0) AS INT) As [Q2 Qty],
COALESCE(p.Amt3, 0.0) As [Q3 Amt],
CAST(COALESCE(p.Qty3, 0) AS INT) As [Q3 Qty],
COALESCE(p.Amt4, 0.0) As [Q4 Amt],
CAST(COALESCE(p.Qty4, 0) AS INT) As [Q4 Qty],
COALESCE(p.Amt1, 0.0) + COALESCE(p.Amt2, 0.0) + COALESCE(p.Amt3, 0.0) + COALESCE(p.Amt4, 0.0) AS [Total Amt],
CAST(COALESCE(p.Qty1, 0) + COALESCE(p.Qty2, 0) + COALESCE(p.Qty3, 0) + COALESCE(p.Qty4, 0) AS INT) As [Total Qty]
FROM(
SELECTCompany,
[Year],
QuarterName,
SUM(Amount) AS [Value]
FROM(
SELECTCompany,
[Year],
'Amt' + STR([Quarter], 1) AS QuarterName,
SUM(Amount) AS Amount
FROMjbmTest
GROUP BYCompany,
[Year],
[Quarter]
UNION ALL
SELECTCompany,
[Year],
'Qty' + STR([Quarter], 1),
SUM(Quantity)
FROMjbmTest
GROUP BYCompany,
[Year],
[Quarter]
) AS d
GROUP BYCompany,
[Year],
QuarterName
) AS t
PIVOT(
SUM(t.[Value])
FOR t.QuarterName IN (Amt1, Amt2, Amt3, Amt4, Qty1, Qty2, Qty3, Qty4)
) AS p
ORDER BYp.Company,
p.[Year]
SQL Profiler
CPU Dur Reads
---- ----- -----
Jeff 2531 4270 5304
JW 2 9938 16935 10608
Peso 2 4078 6846 5304
Peso 3 2422 4451 10608
N 56°04'39.16"
E 12°55'05.25"
June 23, 2008 at 8:06 am
It's funny how changing the CTE into a derived table improved performance like that. I'll dig into that and see why.
--Jeff Moden
Change is inevitable... Change for the better is not.
June 23, 2008 at 8:08 am
The trick was not to convert CTE to derived table.
The performance gain was to subaggregate the table before making the pivot.
N 56°04'39.16"
E 12°55'05.25"
June 23, 2008 at 8:26 am
Same conclusion I came to... Thanks Peter. It also means that it could be done using a CTE with the same performance if the data is pre-aggregated like you did in your good code.
--Jeff Moden
Change is inevitable... Change for the better is not.
June 23, 2008 at 8:29 am
Your original solution will also gain from preaggregration like this
-- Jeff 2
SELECTCompany,
[Year],
SUM(CASE WHEN [Quarter] = 1 THEN Amount ELSE 0.0 END) AS [Q1 Amt],
SUM(CASE WHEN [Quarter] = 1 THEN Quantity ELSE 0 END) AS [Q1 Qty],
SUM(CASE WHEN [Quarter] = 2 THEN Amount ELSE 0.0 END) AS [Q2 Amt],
SUM(CASE WHEN [Quarter] = 2 THEN Quantity ELSE 0 END) AS [Q2 Qty],
SUM(CASE WHEN [Quarter] = 3 THEN Amount ELSE 0.0 END) AS [Q3 Amt],
SUM(CASE WHEN [Quarter] = 3 THEN Quantity ELSE 0 END) AS [Q3 Qty],
SUM(CASE WHEN [Quarter] = 4 THEN Amount ELSE 0.0 END) AS [Q4 Amt],
SUM(CASE WHEN [Quarter] = 4 THEN Quantity ELSE 0 END) AS [Q4 Qty],
SUM(Amount) AS [Total Amt],
SUM(Quantity) AS [Total Qty]
FROM(
SELECTCompany,
[Year],
[Quarter],
SUM(Amount) AS Amount,
SUM(Quantity) AS Quantity
FROMjbmTest
GROUP BYCompany,
[Year],
[Quarter]
) AS d
GROUP BYCompany,
[Year]
ORDER BYCompany,
[Year]
SQL Profiler
CPU Dur Reads
---- ----- -----
Jeff 2531 4270 5304
Jeff 2 1297 2206 5304
JW 2 9938 16935 10608
Peso 2 4078 6846 5304
Peso 3 2422 4451 10608
N 56°04'39.16"
E 12°55'05.25"
June 23, 2008 at 8:46 am
That really puts the stuff on the Pivot method, huh? 🙂
--Jeff Moden
Change is inevitable... Change for the better is not.
June 23, 2008 at 8:48 am
By the way, Peter... you machine is about twice as fast as more poor ol' 6 year old single processor 1.8 GHz box... what are you using?
--Jeff Moden
Change is inevitable... Change for the better is not.
June 23, 2008 at 9:06 am
HP 8710p laptop.
2.4 GHz Intel Centrino Pro
2gb ram.
Single sata 3.5" harddrive.
Microsoft SQL Server 2005 Developer Edition - 9.00.3215.00
If I tell you what I use at home, I have to kill you later.
I have a better db server at home than at work.
N 56°04'39.16"
E 12°55'05.25"
June 23, 2008 at 10:41 am
Excellent work - I did not even think about pre-aggregating the data but it makes sense. But again, as I suspected, the original cross-tab version still performs better than PIVOT.
Jeffrey Williams
“We are all faced with a series of great opportunities brilliantly disguised as impossible situations.”
― Charles R. Swindoll
How to post questions to get better answers faster
Managing Transaction Logs
June 24, 2008 at 8:57 am
Awesome posts and code, guys! Thanks so much for sharing. This answered the exact question I was having. Guess I'll go with the crosstab option.
June 24, 2008 at 3:35 pm
Hey folks... especially Jeff Williams and Peter Larson... thanks for the great help. Like I said, I'm kinda new at 2k5 and you just don't find the kind of outstanding examples in BOL that you two gents cranked out. On top of that, I got a real surprise when Peter did his usual great bit of performance testing.
Heh... Jeff Williams has already started to refer people to this thread. It shows a couple of really good methods not only from the original cross tab code, but in the examples that Jeff Williams and Peter wrote using Pivot. Good stuff here. Thanks again!
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 12 posts - 16 through 26 (of 26 total)
You must be logged in to reply to this topic. Login to reply