Solved

Show a Monthly Count Summary of Multiple Row Entries

Posted on 2013-11-17
12
401 Views
Last Modified: 2013-11-19
Say I've got a SalesTable in an SQL 2005 database which holds multiple entries for each EntityName value, and one of the columns is SalesMonth ...

SELECT EntityName, EntityCode, SalesMonth, [Tour Ref], [Sales Unit], , [GBP Net Margin]      
FROM SalesTable
WHERE
EntityName = 'SalesItemType1'
AND SalesMonth IN
('January', 'February', 'March')

returns 56 rows (29 rows for January, 19 rows for February, 8 rows for March)

SELECT EntityName, EntityCode, SalesMonth, [Tour Ref], [Sales Unit], , [GBP Net Margin]      
FROM SalesTable
WHERE
EntityName = 'SalesItemType73'
AND SalesMonth IN
('January', 'February', 'March')

returns 850 rows (300 rows for January, 350 rows for February, 200 rows for March)

Need to get a monthly count of the entries for every EntityName value on the table, but would need to present in following format

EntityName        EntityCode    January    February    March

SalesItemType1     ITM1            29           19               8
SalesItemType73   ITM73          300         350            200

I'm presuming I would need to use PIVOT, so any suggestions on how best to achieve this using PIVOT, or if there is a better way to do this not using PIVOT ?

Thanks in advance ....
0
Comment
Question by:raymurphy
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
12 Comments
 
LVL 12

Expert Comment

by:Tony303
ID: 39655000
--CREATE A TEMP TABLE

CREATE TABLE #SalesTable (EntityName Varchar(20)
,EntityCode Varchar(5)
,SalesMonth Varchar(10))

--POPULATE THE TEMP TABLE
INSERT INTO #SalesTable (EntityName, EntityCode, SalesMonth)
VALUES ('SalesItemType1','ITM1','January'), ('SalesItemType1','ITM1','January'),('SalesItemType1','ITM1','January'),('SalesItemType1','ITM1','February'),
('SalesItemType1','ITM1','February'),('SalesItemType1','ITM1','March'),('SalesItemType1','ITM1','March'), ('SalesItemType1','ITM1','March'), ('SalesItemType1','ITM1','March'), 
('SalesItemType1','ITM1','March'), ('SalesItemType73','ITM73','January'), ('SalesItemType73','ITM73','January'), ('SalesItemType73','ITM73','January'),('SalesItemType73','ITM73','January'),
('SalesItemType73','ITM73','February'),('SalesItemType73','ITM73','February'),('SalesItemType73','ITM73','February'),('SalesItemType73','ITM73','March'),('SalesItemType73','ITM73','March'),
('SalesItemType73','ITM73','March'),('SalesItemType73','ITM73','March'),('SalesItemType73','ITM73','March'),('SalesItemType73','ITM73','March')


--PIVOT
SELECT *
FROM #SalesTable AS s
PIVOT (
COUNT(SalesMonth) FOR SalesMonth
IN (January,February,March)) AS pvt

Open in new window

0
 
LVL 3

Assisted Solution

by:Onn Light
Onn Light earned 100 total points
ID: 39655745
Hi  Raymurphy

One way of not using PIVOT is by using CASE, as below


SELECT EntityName, EntityCode
, SUM( CASE SalesMonth WHEN 'January' THEN 1 ELSE 0 END) AS January
, SUM( CASE SalesMonth WHEN 'February' THEN 1 ELSE 0 END) AS February
, SUM( CASE SalesMonth WHEN 'March' THEN 1 ELSE 0 END) AS March
FROM SalesTable
WHERE  SalesMonth IN ('January', 'February', 'March')
GROUP BY EntityName, EntityCode
ORDER BY EntityName, EntityCode

Open in new window



Thanks and Regards
onn

Edit: Corrected Column Alias for January, February and March
0
 

Author Comment

by:raymurphy
ID: 39656036
Thanks a lot for the quick responses with both solutions - I'll set up a test of these later today, so will get back once I've done some testing of both solutions ....
0
Free learning courses: Active Directory Deep Dive

Get a firm grasp on your IT environment when you learn Active Directory best practices with Veeam! Watch all, or choose any amount, of this three-part webinar series to improve your skills. From the basics to virtualization and backup, we got you covered.

 

Author Comment

by:raymurphy
ID: 39656189
Testing now ...
0
 

Author Comment

by:raymurphy
ID: 39656207
Sorry - Don't seem to be able to post a long comment from my current machine, so have put comments in attached file ..
testprogresscomment.txt
0
 

Author Comment

by:raymurphy
ID: 39657292
OK, have now done some initial testing, but still need to do some further tests later today.

With the onnlight solution, that code works fine against my live table (which contains some extra columns in addition to the columns shown in my question).

With the Tony303 solution, using the temporary table code snippet, I can see that the PIVOT does produce the expected output - but when I apply that approach
against my live table (which contains extra columns in addition to the columns shown in my question, meaning that I don't particularly want to say SELECT * FROM
SalesTable) in SQL Server 2005, I did hit an odd problem. If I code my statement against my live table as  :

SELECT EntityName, EntityCode, SalesMonth
FROM SalesTable AS s
PIVOT (
COUNT(SalesMonth) FOR SalesMonth
IN (January,February,March)) AS pvt

then I get an error of Invalid column name 'SalesMonth', so I'm not sure why that is. What is odd is that if i say SELECT EntityName, EntityCode, SalesMonth
FROM SalesTable in the  temporary table code snippet then I get the same error of Invalid column name 'SalesMonth' ...... But SELECT * FROM SalesTable in
the temporary code snippet does work OK - so I'm just trying to understand why SELECT * works but with SELECT explicitly naming the columns gives
the Invalid column name 'SalesMonth' error ??
0
 

Author Comment

by:raymurphy
ID: 39657444
Just a question on the onnlight solution, if that's OK. The SalesTable also has a SalesYear column. Could your solution be extended so that it could handle multiple years when presenting the monthly figures output, so that it would look something like :

Jan 2013   Feb 2013  Mar 2013 .... Dec 2013   Jan 2014  Feb 2014
0
 
LVL 12

Expert Comment

by:Tony303
ID: 39657642
Hey Ray,

I don't know the exact answer to your Select * question but here is a rework of my example, expanded somewhat to invlude your other fields.

I hope it helps.
I must admit I can't stand PIVOT, I generally export the data to Excel and pivot it all up there in a fraction of the time!!

T

--CREATE A TEMP TABLE

CREATE TABLE #SalesTable (EntityName Varchar(20)
,EntityCode Varchar(5)
,SalesMonth Varchar(10)
,[Tour Ref] VARCHAR(5) 
,[Sales Unit] VARCHAR(2)
,[GBP Net Margin] MONEY
)

--POPULATE THE TEMP TABLE
INSERT INTO #SalesTable (EntityName, EntityCode, SalesMonth, [Tour Ref],[Sales Unit],[GBP Net Margin])
VALUES ('SalesItemType1','ITM1','January','ABC','ZY',30.25),
('SalesItemType1','ITM1','January','ABC','ZY',19.56),
('SalesItemType1','ITM1','January','EFG','ZY',25.32),
('SalesItemType1','ITM1','February','EFG','XC',25.25),
('SalesItemType1','ITM1','March','ABC','ZY',22.50),
('SalesItemType1','ITM1','February','ABC','XC',22.30),
('SalesItemType73','ITM73','February','ABC','XC',22.30),
('SalesItemType73','ITM73','February','ABC','XC',25.78),
('SalesItemType73','ITM73','January','EFG','ZY',33.33),
('SalesItemType73','ITM73','January','ABC','XC',42.50),
('SalesItemType73','ITM73','January','ABC','XC',19.80),
('SalesItemType73','ITM73','March','ABC','XC',19.80),
('SalesItemType73','ITM73','March','EFG','ZY',28.60)


SELECT *
FROM  #SalesTable

--PIVOT
SELECT *
FROM #SalesTable AS s
PIVOT (
COUNT(SalesMonth) FOR SalesMonth
IN (January,February,March)) AS pvt

--PIVOT WITH SUM PER MONTH
SELECT EntityName, EntityCode, [Tour Ref],[Sales Unit],  SUM([January]) AS JanuarySalesCount, SUM([February]) AS FebruarySalesCount, SUM([March]) AS MarchSalesCount
FROM
(SELECT  EntityName, EntityCode, [Tour Ref],[Sales Unit],[January], [February], [March]
FROM #SalesTable AS s
PIVOT (
COUNT(SalesMonth) FOR SalesMonth
IN (January,February,March)) AS pvt) a
GROUP BY  EntityName, EntityCode, [Tour Ref],[Sales Unit]

--PIVOT WITH AVG MARGIN
SELECT EntityName, EntityCode, [Tour Ref],[Sales Unit],  SUM([January]) AS JanuarySalesCount, SUM([February]) AS FebruarySalesCount, SUM([March]) AS MarchSalesCount,AVG([GBP Net Margin])  AS AverageMarginALLMONTHS
FROM
(SELECT  EntityName, EntityCode, [Tour Ref],[Sales Unit],[January], [February], [March],[GBP Net Margin]
FROM #SalesTable AS s
PIVOT (
COUNT(SalesMonth) FOR SalesMonth
IN (January,February,March)) AS pvt) a
GROUP BY  EntityName, EntityCode, [Tour Ref],[Sales Unit]

Open in new window

0
 
LVL 12

Accepted Solution

by:
Tony303 earned 400 total points
ID: 39657834
Rework with years being included.
My example and onnlight's too...


--CREATE A TEMP TABLE

CREATE TABLE #SalesTable (EntityName Varchar(20)
,EntityCode Varchar(5)
,SalesMonth Varchar(10)
,[Tour Ref] VARCHAR(5) 
,[Sales Unit] VARCHAR(2)
,[GBP Net Margin] MONEY
,[SalesYear] VARCHAR(4)
)

--POPULATE THE TEMP TABLE
INSERT INTO #SalesTable (EntityName, EntityCode, SalesMonth, [Tour Ref],[Sales Unit],[GBP Net Margin], SalesYear)
VALUES ('SalesItemType1','ITM1','January','ABC','ZY',30.25,2013),
('SalesItemType1','ITM1','January','ABC','ZY',19.56,2012),
('SalesItemType1','ITM1','January','EFG','ZY',25.32,2012),
('SalesItemType1','ITM1','February','EFG','XC',25.25,2013),
('SalesItemType1','ITM1','March','ABC','ZY',22.50,2013),
('SalesItemType1','ITM1','February','ABC','XC',22.30,2013),
('SalesItemType73','ITM73','February','ABC','XC',22.30,2012),
('SalesItemType73','ITM73','February','ABC','XC',25.78,2012),
('SalesItemType73','ITM73','January','EFG','ZY',33.33,2013),
('SalesItemType73','ITM73','January','ABC','XC',42.50,2013),
('SalesItemType73','ITM73','January','ABC','XC',19.80,2012),
('SalesItemType73','ITM73','March','ABC','XC',19.80,2012),
('SalesItemType73','ITM73','March','EFG','ZY',28.60,2012)


SELECT *
FROM  #SalesTable
ORDER BY EntityName,SalesYear

--PIVOT
SELECT *
FROM #SalesTable AS s
PIVOT (
COUNT(SalesMonth) FOR SalesMonth
IN (January,February,March)) AS pvt

--PIVOT WITH SUM PER MONTH
SELECT EntityName, EntityCode, [Tour Ref],[Sales Unit], SalesYear, SUM([January]) AS JanuarySalesCount, SUM([February]) AS FebruarySalesCount, SUM([March]) AS MarchSalesCount
FROM
(SELECT  EntityName, EntityCode, [Tour Ref],[Sales Unit], SalesYear, [January], [February], [March]
FROM #SalesTable AS s
PIVOT (
COUNT(SalesMonth) FOR SalesMonth
IN (January,February,March)) AS pvt) a
GROUP BY  EntityName, EntityCode, SalesYear,[Tour Ref],[Sales Unit]
ORDER BY  EntityName,SalesYear

--PIVOT WITH AVG MARGIN
SELECT EntityName, EntityCode, [Tour Ref],[Sales Unit], SalesYear, SUM([January]) AS JanuarySalesCount, SUM([February]) AS FebruarySalesCount, SUM([March]) AS MarchSalesCount,AVG([GBP Net Margin])  AS AverageMarginALLMONTHS
FROM
(SELECT  EntityName, EntityCode, [Tour Ref],[Sales Unit],SalesYear,[January], [February], [March],[GBP Net Margin]
FROM #SalesTable AS s
PIVOT (
COUNT(SalesMonth) FOR SalesMonth
IN (January,February,March)) AS pvt) a
GROUP BY  EntityName, EntityCode, [Tour Ref],[Sales Unit],SalesYear
ORDER BY EntityName,SalesYear

--Onnlight method
SELECT EntityName, EntityCode, [Tour Ref],[Sales Unit], SalesYear, AVG([GBP Net Margin]) AS  AverageMarginALLMONTHS
, SUM( CASE SalesMonth WHEN 'January' THEN 1 ELSE 0 END) AS January
, SUM( CASE SalesMonth WHEN 'February' THEN 1 ELSE 0 END) AS February
, SUM( CASE SalesMonth WHEN 'March' THEN 1 ELSE 0 END) AS March
FROM #SalesTable
WHERE  SalesMonth IN ('January', 'February', 'March')
GROUP BY EntityName, EntityCode, [Tour Ref],[Sales Unit], SalesYear
ORDER BY EntityName, SalesYear

Open in new window

0
 

Author Closing Comment

by:raymurphy
ID: 39660182
Thanks a lot for both of these very helpful solutions, much appreciated. As both solutions were appropriate, have tried to split the points accordingly, so hope that's OK with you both ...
0
 
LVL 12

Expert Comment

by:Tony303
ID: 39660188
No problem,
What method are you going to run with?
0
 

Author Comment

by:raymurphy
ID: 39660494
Actually been using

--Onnlight method
SELECT EntityName, EntityCode, [Tour Ref],[Sales Unit], SalesYear, AVG([GBP Net Margin]) AS  AverageMarginALLMONTHS
, SUM( CASE SalesMonth WHEN 'January' THEN 1 ELSE 0 END) AS January
, SUM( CASE SalesMonth WHEN 'February' THEN 1 ELSE 0 END) AS February
, SUM( CASE SalesMonth WHEN 'March' THEN 1 ELSE 0 END) AS March
FROM #SalesTable
WHERE  SalesMonth IN ('January', 'February', 'March')
GROUP BY EntityName, EntityCode, [Tour Ref],[Sales Unit], SalesYear
ORDER BY EntityName, SalesYear

Mainly because of the PIVOT solution problem where SELECT * worked but with SELECT explicitly naming the columns gives the Invalid column name 'SalesMonth' error ...
0

Featured Post

Forrester Webinar: xMatters Delivers 261% ROI

Guest speaker Dean Davison, Forrester Principal Consultant, explains how a Fortune 500 communication company using xMatters found these results: Achieved a 261% ROI, Experienced $753,280 in net present value benefits over 3 years and Reduced MTTR by 91% for tier 1 incidents.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Load balancing is the method of dividing the total amount of work performed by one computer between two or more computers. Its aim is to get more work done in the same amount of time, ensuring that all the users get served faster.
Ever wondered why sometimes your SQL Server is slow or unresponsive with connections spiking up but by the time you go in, all is well? The following article will show you how to install and configure a SQL job that will send you email alerts includ…
Familiarize people with the process of utilizing SQL Server functions from within Microsoft Access. Microsoft Access is a very powerful client/server development tool. One of the SQL Server objects that you can interact with from within Microsoft Ac…
Via a live example, show how to set up a backup for SQL Server using a Maintenance Plan and how to schedule the job into SQL Server Agent.

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question