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
This website stores cookies on your computer.
These cookies are used to improve your website experience and provide more personalized services to you, both on this website and through other media.
To find out more about the cookies we use, see our Privacy Policy