Solved

Show a Monthly Count Summary of Multiple Row Entries

Posted on 2013-11-17
12
399 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
  • 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
Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

 

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

Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

Question has a verified solution.

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

In this article we will get to know that how can we recover deleted data if it happens accidently. We really can recover deleted rows if we know the time when data is deleted by using the transaction log.
Ever needed a SQL 2008 Database replicated/mirrored/log shipped on another server but you can't take the downtime inflicted by initial snapshot or disconnect while T-logs are restored or mirror applied? You can use SQL Server Initialize from Backup…
Via a live example, show how to backup a database, simulate a failure backup the tail of the database transaction log and perform the restore.
Viewers will learn how the fundamental information of how to create a table.

786 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