Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pivot vs Case T-sql efficiency

I am trying to figure out which way is more efficient. I tried to use Sql Fiddle but it didn't seem to recognize PIVOT or UNION What tools or statistics can I look at to determine which is more efficient.

CREATE TABLE T
(
  PersonNum INT
 ,WeekOf DATETIME
 ,ActivityType1 INT
 ,ActivityType2 INT
 ,Hours INT
)

INSERT INTO T VALUES(1,'11/2/2014',5,0,40)
INSERT INTO T VALUES(1,'11/2/2014',1,0,5)
INSERT INTO T VALUES(1,'11/2/2014',1,0,8)
INSERT INTO T VALUES(1,'11/2/2014',2,1,6)
INSERT INTO T VALUES(1,'11/2/2014',2,2,2)
INSERT INTO T VALUES(1,'11/2/2014',2,3,9)
INSERT INTO T VALUES(1,'11/2/2014',2,4,7)

INSERT INTO T VALUES(1,'11/9/2014',5,0,40)
INSERT INTO T VALUES(1,'11/9/2014',1,0,2)
INSERT INTO T VALUES(1,'11/9/2014',1,0,6)
INSERT INTO T VALUES(1,'11/9/2014',2,1,7)
INSERT INTO T VALUES(1,'11/9/2014',2,2,2)
INSERT INTO T VALUES(1,'11/9/2014',2,3,3)
INSERT INTO T VALUES(1,'11/9/2014',2,4,5)

Method 1

SELECT 
  PersonNum
, WeekOf
, SUM(CASE WHEN ActivityType1 = 5 THEN Hours ELSE 0 END) AS Beginning
, SUM(CASE WHEN ActivityType1 = 1 THEN Hours ELSE 0 END) AS Plus
, SUM(CASE WHEN ActivityType1 = 2 AND ActivityType2 <> 3 THEN Hours ELSE 0 END) AS Minus
, SUM(CASE WHEN ActivityType1 = 2 AND ActivityType2 = 3 THEN Hours ELSE 0 END) AS MinusSpecial
FROM T
GROUP BY 
  PersonNum
, WeekOf

Method 2

SELECT
  PersonNum
, WeekOf
, [Beginning]
, [Plus]
, [Minus]
, [Minus Special]
FROM
(
  SELECT
    PersonNum
  , WeekOf
  , 'Beginning' AS ColumnType
  , Hours
  FROM T
  WHERE
    ActivityType1 = 5 
  UNION
  SELECT
    PersonNum
  , WeekOf
  , 'Plus' AS ColumnType
  , Hours
  FROM T
  WHERE
    ActivityType1 = 1 
  UNION
  SELECT
    PersonNum
  , WeekOf
  , 'Minus' AS ColumnType
  , Hours
  FROM T
  WHERE
      ActivityType1 = 2 
  AND ActivityType2 <> 3
   UNION
  SELECT
    PersonNum
  , WeekOf
  , 'Minus Special' AS ColumnType
  , Hours
  FROM T
  WHERE
      ActivityType1 = 2 
  AND ActivityType2 = 3
    ) Data  
PIVOT 
(SUM(Hours)
FOR ColumnType IN ([Beginning]                
                  ,[Plus]
                  ,[Minus]
                  ,[Minus Special])
) pvt 
like image 893
Mike Avatar asked Nov 30 '25 06:11

Mike


1 Answers

May I suggest a rewrite of your PIVOT query so you don't have to hit the table 5 times.

select P.PersonNum,
       P.WeekOf,
       P.Beginning,
       P.Plus,
       P.Minus,
       P.MinusSpecial
from (
     select T.PersonNum,
            T.WeekOf,
            T.Hours,
            case ActivityType1 
             when 5 then 'Beginning'  
             when 1 then 'Plus'
             when 2 then case ActivityType2
                           when 3 then 'MinusSpecial'
                           else 'Minus'
                         end
            end as ColumnType
     from T
     ) as T
pivot (sum(T.Hours) for T.ColumnType in (Beginning, Plus, MinusSpecial, Minus)) as P

With that you will probably get the same query plan as your group by query and about the same performance.

like image 60
Mikael Eriksson Avatar answered Dec 02 '25 05:12

Mikael Eriksson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!