• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 748
  • Last Modified:

Adding ROW and COLUMN subtotals and percentages to TSQL output

See attached workbook for examples of:
- SOURCE data (temp table XROADS_RADIOLOGY)
- Existing OUTPUT
- Desired OUTPUT
...each on its own tab.

Starting with SOURCE DATA and using the following query:
SELECT Provider, Type, QTY,(POINTS1 + POINTS2) as Points
FROM XROADS_RADIOLOGY
ORDER BY Type,Provider

I get the OUTPUT EXISTING shown in the attachment.

How may I modify my query so as to include (a) subtotal of QTY and Points by Type, and (b) Percentage of points by provider for each Type.  See OUTPUT DESIRED in the attachment.



 DATA-SAMPLES.xls
0
bleonardi
Asked:
bleonardi
  • 5
  • 4
1 Solution
 
matthewrhoadesCommented:
SELECT Provider, Type, QTY,(POINTS1 + POINTS2) as Points, (POINTS1+POINTS2)/SUM(POINTS1+POINTS2)
FROM XROADS_RADIOLOGY
GROUP BY Provider, Type, QTY
ORDER BY Type,Provider

If you get an error about one of the fields not being in the group by clause or an aggregate, you can just add it to the group by clause.
0
 
bleonardiAuthor Commented:
I did get an error as you thought, and changed the query to this and it ran:

SELECT Provider, Type, QTY,(POINTS1 + POINTS2) as Points, (POINTS1+POINTS2)/SUM(POINTS1+POINTS2)
FROM XROADS_RADIOLOGY
GROUP BY Provider, Type, QTY, points1, points2
ORDER BY Type,Provider

However the new column was all "1"'s (I suppose there needs to be some data conversion?).

Also, there is no subtotal by Type.
0
 
Theand1978Commented:
It makes use of temp table and it is a 2 stage process that could probably be improved upon but this is my initial approach and solution.

Image represents what the results will look lik

IF Object_ID( 'tempdb..#Temp', 'U' ) IS NOT NULL DROP TABLE #Temp
GO

   --calculate the points
   SELECT Provider, [Type], QTY, (Points1+Points2) AS Points, 0.0 AS [Percent], 1 AS Ord
     INTO #Temp
     FROM SourceData
    UNION ALL
  -- Calculate the subtotals
  SELECT 'total', [Type], sum(QTY), sum( ( points1+points2) ), (sum( ( points1+points2) ) / sum( ( points1+points2) ) * 100), 2 
    FROM SourceData
GROUP BY [Type]
GO

--Calculate the percent 
UPDATE T 
   SET T.[Percent] = convert( float, T.Points ) / convert( float, A.Points ) * 100
  FROM #Temp T
  JOIN (SELECT [Type], Points FROM #Temp WHERE Provider = 'total' ) A ON A.[Type] = T.[Type] 
GO

  SELECT Provider, [Type], QTY, Points, [Percent] 
    FROM #Temp
ORDER BY [Type], Ord, Provider
GO

Open in new window

results.jpg
0
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

 
Theand1978Commented:
Another version with out using a Temp Table and just selects / Derived table and a union
SELECT Provider, 
          S.[Type], 
          QTY, 
          (Points1+Points2) AS Points, 
          Convert( Decimal( 5,1), convert( Decimal(5,1) , (Points1+Points2)) / Convert( Decimal(5,1), T.Total) * 100.0 ) as [Percent]
     FROM SourceData S
     JOIN ( SELECT [Type], sum( ( points1+points2) ) AS Total FROM SourceData GROUP BY [Type] ) T ON T.[Type] = S.[Type]
    UNION ALL
  -- Calculate the subtotals
  SELECT 'total', [Type], sum(QTY), sum( ( points1+points2) ), (sum( ( points1+points2) ) / sum( ( points1+points2) ) * 100)
    FROM SourceData
GROUP BY [Type]
Order by [Type], Points
GO

Open in new window

0
 
bleonardiAuthor Commented:
Thank Thean1978.  I ran and got this message:

Server: Msg 209, Level 16, State 1, Line 1
Ambiguous column name 'TYPE'.
0
 
Theand1978Commented:
I am assuming you ran the second version ( with out the temp table )
0
 
bleonardiAuthor Commented:
Correct
0
 
Theand1978Commented:
Try this. I just aliased every column in the SQL, I don't see how it could be "ambiguous".
SELECT S.Provider, 
          S.[Type], 
          S.QTY, 
          (S.Points1+S.Points2) AS Points, 
          Convert( Decimal( 5,1), convert( Decimal(5,1) , (S.Points1+S.Points2)) / Convert( Decimal(5,1), T.Total) * 100.0 ) as [Percent]
     FROM SourceData S
     JOIN ( SELECT [Type], sum( ( points1+points2) ) AS Total FROM SourceData GROUP BY [Type] ) T ON T.[Type] = S.[Type]
    UNION ALL
  -- Calculate the subtotals
  SELECT 'total', ST.[Type], sum(ST.QTY), sum( ( ST.points1+ST.points2) ), (sum( ( ST.points1+ST.points2) ) / sum( ( ST.points1+ST.points2) ) * 100)
    FROM SourceData ST
GROUP BY ST.[Type]
Order by [Type], Points

Open in new window

0
 
bleonardiAuthor Commented:
I ran the new version and got the same error.  

After changing the last line to
   Order by S.[Type], Points
it worked great!

Points awarded.  Thanks
0
 
Theand1978Commented:
It was a pleasure,

And Thank You !! that was a nice little challenge to help my day along.

Take Care
   Clint
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now