Crosstab query to determine ving margins

K

Krish

I have a table that has fields such as date, Invoice#, salesrep# and sales
margin dollars for every product sold listed in a Invoice. I would like to
populate a crosstab query preferably as follows.
Group by Salesrep as row
Count number of Invoices as value.
Group Sales Margin dollars like >50,50-75,75-100,100-150, 150-300,300 and
above as columns.
Where date range is between ## and ##.
Which query is the best for getting the results?
My goal is to determine the poor performing salesrep.

Thanks for all the help.
 
T

Tom Ellison

Dear Krish:

Here's what I propose:

SELECT Salesrep, COUNT(*) AS Invoices,
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] <= 50)
AS [50],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 50
AND T1.[sales margin] <= 75)
AS [50 - 75],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 75
AND T1.[sales margin] <= 100)
AS [75 - 100],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 100
AND T1.[sales margin] <= 150)
AS [100 - 150],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 150
AND T1.[sales margin] <= 300)
AS [150 - 300],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 300)
AS [300+],
FROM YourTable T
WHERE [date] BETWEEN #1/1/2004# AND #12/31/2004#
GROUP BY Salesrep

This uses subqueries to categorize the 6 ranges of Sales Margin.

You must replace "YourTable" in the above with the actual name of your table
(or query) at 7 places in the above. Also, please check my spelling of your
column names.

Tom Ellison
 
G

Guest

Try using Partition --
Sales Margin :partition([Sales Margin],0,999999,50)
This will group by 50 from zero to 999999.


Tom Ellison said:
Dear Krish:

Here's what I propose:

SELECT Salesrep, COUNT(*) AS Invoices,
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] <= 50)
AS [50],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 50
AND T1.[sales margin] <= 75)
AS [50 - 75],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 75
AND T1.[sales margin] <= 100)
AS [75 - 100],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 100
AND T1.[sales margin] <= 150)
AS [100 - 150],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 150
AND T1.[sales margin] <= 300)
AS [150 - 300],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 300)
AS [300+],
FROM YourTable T
WHERE [date] BETWEEN #1/1/2004# AND #12/31/2004#
GROUP BY Salesrep

This uses subqueries to categorize the 6 ranges of Sales Margin.

You must replace "YourTable" in the above with the actual name of your table
(or query) at 7 places in the above. Also, please check my spelling of your
column names.

Tom Ellison

Krish said:
I have a table that has fields such as date, Invoice#, salesrep# and sales
margin dollars for every product sold listed in a Invoice. I would like to
populate a crosstab query preferably as follows.
Group by Salesrep as row
Count number of Invoices as value.
Group Sales Margin dollars like >50,50-75,75-100,100-150, 150-300,300 and
above as columns.
Where date range is between ## and ##.
Which query is the best for getting the results?
My goal is to determine the poor performing salesrep.

Thanks for all the help.
 
D

Duane Hookom

I would create a table of sales ranges.
tblSalesRanges
MinMargin MaxMargin Title
0 50 "From 0 to 50"
50 75 "From 50 to 100"
75 100 "From 75 to 100"
100 150 "From 100 to 150"
150 300 "From 150 to 300"
300 99999 "From 300 to Above"

You can add this to your query and set the criteria under the Sales Margin
column to:
=MinMargin AND < MaxMargin

Add the Title to your query to create your column headings.

This solution allows you to change data values WHEN you want to change
ranges.

--
Duane Hookom
MS Access MVP


KARL DEWEY said:
Try using Partition --
Sales Margin :partition([Sales Margin],0,999999,50)
This will group by 50 from zero to 999999.


Tom Ellison said:
Dear Krish:

Here's what I propose:

SELECT Salesrep, COUNT(*) AS Invoices,
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] <= 50)
AS [50],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 50
AND T1.[sales margin] <= 75)
AS [50 - 75],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 75
AND T1.[sales margin] <= 100)
AS [75 - 100],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 100
AND T1.[sales margin] <= 150)
AS [100 - 150],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 150
AND T1.[sales margin] <= 300)
AS [150 - 300],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 300)
AS [300+],
FROM YourTable T
WHERE [date] BETWEEN #1/1/2004# AND #12/31/2004#
GROUP BY Salesrep

This uses subqueries to categorize the 6 ranges of Sales Margin.

You must replace "YourTable" in the above with the actual name of your
table
(or query) at 7 places in the above. Also, please check my spelling of
your
column names.

Tom Ellison

Krish said:
I have a table that has fields such as date, Invoice#, salesrep# and
sales
margin dollars for every product sold listed in a Invoice. I would like
to
populate a crosstab query preferably as follows.
Group by Salesrep as row
Count number of Invoices as value.
Group Sales Margin dollars like >50,50-75,75-100,100-150, 150-300,300
and
above as columns.
Where date range is between ## and ##.
Which query is the best for getting the results?
My goal is to determine the poor performing salesrep.

Thanks for all the help.
 
V

Vincent Johns

Although I'm not sure about this, my interpretation of what you asked
for is a little different from Tom Ellison's. The Query that he posted
will do a good job of displaying totals, and that's what I originally
thought you wanted. But looking at your question again caused me to
think that you really wanted to know how many invoices in each price
range a salesman issued (during the time period you specified). So, if
the Query that Tom gave you is what you need, you may ignore the rest of
this message. (It presents a solution based on an alternative
interpretation of your request.)

Suppose we have sales data that look like this:

[Sales]

date Invoice# salesrep# sales margin
dollars
---------- -------- --------- ------------
11/21/2005 021 Jim $105.00
11/21/2005 022 Sue $98.00
10/21/2005 002 Sue $85.00
11/21/2005 023 Jim $205.00
5/18/2005 033 Sue $315.00

I added a new Table to identify the categories into which you wanted to
classify the sales representatives:

[Levels]

Levels_ID Range Floor
--------- -------- --------
1 <50 $0.00
2 50-75 $50.00
3 75-100 $75.00
4 100-150 $100.00
5 150-300 $150.00
6 300+ $300.00

(The second field, [Range], I was originally going to use in the
Crosstab Query, but it didn't do exactly what I wanted, so I don't
actually use it there.)

For these data, Tom Ellison's Query (slightly revised) would produce the
following results in Query Datasheet View:

salesrep# Invoices 50 50-75 75-100 100-150 150-300 300+
--------- -------- -- ----- ------ ------- ------- -------
Jim 2 $105.00 $205.00
Sue 3 $183.00 $315.00

To display these data according to my take on your request, I defined 3
Queries. The first one calculates the category to which an invoice
belongs. (You might want to combine these, for example, using monthly
totals, but I think that's not what you asked for.)

[Q_1_Levels] SQL:

SELECT S.[salesrep#], S.[Invoice#],
S.[sales margin dollars], Max(L.Floor) AS LevelBoundary
FROM Levels AS L, Sales AS S
WHERE (((L.Floor)<![sales margin dollars]))
GROUP BY S.[salesrep#], S.[Invoice#],
S.[sales margin dollars], S.date
HAVING (((S.date) Between #1/1/2004# And #12/31/2005#));


[Q_1_Levels] Query Datasheet view:

salesrep# Invoice# sales margin LevelBoundary
dollars
--------- -------- ------------ -------------
Jim 021 $105.00 $100.00
Jim 023 $205.00 $150.00
Sue 002 $85.00 $75.00
Sue 022 $98.00 $75.00
Sue 033 $315.00 $300.00

The [LevelBoundary] field identifies the category that we will use.
Only one date range is used; for other ranges, you'd need to change the
Query design.

The next Query counts the number of invoices that each salesman has in
each category (during the specified time period).

[Q_2_SalesrepLevels] SQL:

SELECT Q1.[salesrep#], L.Range,
Count(Q1.[Invoice#]) AS Invoices
FROM Q_1_Levels AS Q1 INNER JOIN Levels AS L
ON Q1.LevelBoundary = L.Floor
GROUP BY Q1.[salesrep#], L.Range, Q1.LevelBoundary
ORDER BY Q1.[salesrep#], Q1.LevelBoundary;

[Q_2_SalesrepLevels] Query Datasheet view:

salesrep# Range Invoices
--------- ------- --------
Jim 100-150 1
Jim 150-300 1
Sue 75-100 2
Sue 300+ 1

The 3rd Query runs the Crosstab, displaying numbers of invoices (no
dollar amounts) in each category.

[Q_3_Salesrep_Crosstab] SQL:

TRANSFORM Max(Q2.Invoices) AS MaxOfInvoices
SELECT Q2.[salesrep#]
FROM Q_2_SalesrepLevels AS Q2
GROUP BY Q2.[salesrep#]
ORDER BY Q2.[salesrep#]
PIVOT Q2.Range In ("<50","50-75","75-100",
"100-150","150-300","300+");

Sadly, I couldn't find a way to specify the column headings ("<50",
etc.) without re-entering them. I dislike maintaining duplicate lists
in a database, as any changes must be made multiple times, but I
couldn't find any other way to specify them. So you'll find the same
list of values in the [Levels].[Range] Table and in the
[Q_3_Salesrep_Crosstab] definition. (In Query Design View, right-click
on the upper panel, choose properties, specify values in Column Headings.)

[Q_3_Salesrep_Crosstab] Query Datasheet view:

salesrep# <50 50-75 75-100 100-150 150-300 300+
--------- --- ----- ------ ------- ------- ----
Jim 1 1
Sue 2 1

This is close to what I (now) think you were asking for. Of course,
these Queries can be modified to add date ranges, totals, etc.

-- Vincent Johns <[email protected]>
Please feel free to quote anything I say here.


Tom said:
Dear Krish:

Here's what I propose:

SELECT Salesrep, COUNT(*) AS Invoices,
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] <= 50)
AS [50],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 50
AND T1.[sales margin] <= 75)
AS [50 - 75],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 75
AND T1.[sales margin] <= 100)
AS [75 - 100],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 100
AND T1.[sales margin] <= 150)
AS [100 - 150],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 150
AND T1.[sales margin] <= 300)
AS [150 - 300],
(SELECT SUM([sales margin])
FROM YourTable T1
WHERE T1.Salesrep = T.SalesREP
AND T1.[sales margin] > 300)
AS [300+],
FROM YourTable T
WHERE [date] BETWEEN #1/1/2004# AND #12/31/2004#
GROUP BY Salesrep

This uses subqueries to categorize the 6 ranges of Sales Margin.

You must replace "YourTable" in the above with the actual name of your table
(or query) at 7 places in the above. Also, please check my spelling of your
column names.

Tom Ellison

I have a table that has fields such as date, Invoice#, salesrep# and sales
margin dollars for every product sold listed in a Invoice. I would like to
populate a crosstab query preferably as follows.
Group by Salesrep as row
Count number of Invoices as value.
Group Sales Margin dollars like >50,50-75,75-100,100-150, 150-300,300 and
above as columns.
Where date range is between ## and ##.
Which query is the best for getting the results?
My goal is to determine the poor performing salesrep.

Thanks for all the help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top