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
Solved

Show a Monthly Count Summary of Multiple Row Entries

Posted on 2013-11-17
12
400 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
Comprehensive Backup Solutions for Microsoft

Acronis protects the complete Microsoft technology stack: Windows Server, Windows PC, laptop and Surface data; Microsoft business applications; Microsoft Hyper-V; Azure VMs; Microsoft Windows Server 2016; Microsoft Exchange 2016 and SQL Server 2016.

 

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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Introduction In my previous article (http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SSIS/A_9150-Loading-XML-Using-SSIS.html) I showed you how the XML Source component can be used to load XML files into a SQL Server database, us…
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
Using examples as well as descriptions, and references to Books Online, show the documentation available for date manipulation functions and by using a select few of these functions, show how date based data can be manipulated with these functions.
Viewers will learn how to use the SELECT statement in SQL to return specific rows and columns, with various degrees of sorting and limits in place.

839 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