|
Posted by bobc on 10/02/07 18:48
I hope this makes the problem more understandable. Thanks to anyone
who takes an interest.
I want to display a series of grids on a .net web page.
The grids would make up a dashboard that provides a snapshot of sales
and marketing activities, customer status information, forecasts and
objectives, etc.
Activities are grouped into grids by customer status (lead, active
customer, under contract, closed buyer) because the activities and
milestones (represented by the bins) vary for each status.
Activites(1-n) in a single grid are not all pulled from the same table
or view, and some of the criteria would differ. So I don't believe a
GROUP BY clause on a single dataset would fit the problem.
In the example below, activity1 represents sales leads that are
currently 1, 7, 20, 25 and 60 days old, respectively. These values
will come from the Prospects table.
Activity2 might represent forecasts for current sales leads at the
same intervals. These values would come from a sales objectives
table.
1 7 20 25 60
activity1 0 0 0 0 0
activity2 0 0 0 0 0
activity3 0 0 0 0 0
activity4 0 0 0 0 0
....
activityn 0 0 0 0 0
Another grid might have fewer or more bins.
My goal is to minimize:
# open connections to the database
# calls to stored procedures
length of code in stored procedures or udf's
maintenance as activities or bins are added or dropped
My "procedural language programmer" solution would be to open one
connection to the db and grab all the information at once, retrieving
all the activity rows in individual activity parameters. I could then
parse each parameter value into the appropriate bins with vb behind
the page.
Another approach, which Erland suggested, is to return a dataset.
I have listed (below) simplified versions of the Prospect table
description and the proc GetLeadsByStatusAge.
I use bin variables @d1-@d5 rather than literals 1, 7, 20, 25, 60
because I'm hoping there is a way to programmatically vary the number
and values of bin boundaries, through input parameters or some other
means, and make this thing elegant. In other words, I'd like to
create a black box that can process any activity I ask it to,
regardless of where the data comes from, how many bins apply, or what
the bin boundaries are.
GetLeadsByStatusAge returns an array string, but could just as easily
insert a row into a temporary table.
Thanks to Erland for suggesting the use of CASE. I've used it before
in a similar way, but sometimes forget its power.
Thanks to everyone who takes a look at it.
BobC
/ * Simplified definition of the Prospects table: */
CREATE TABLE Prospects (
CommunityCode varchar (3),
LastName1 varchar (30),
FirstName1 varchar (15),
InitialContactDate datetime,
ProspectStatus varchar (1),
StatusChangeDate datetime
)
GO
/* Simplified procedure intended to return one row of the grid on
my .net page. */
CREATE PROCEDURE GetLeadsByStatusAge
@CommCode char(3),
@Result varchar(255) OUTPUT
AS
SELECT @Result =
(SELECT
ltrim(str(SUM(CASE
DATEDIFF(day, statuschangedate, CURRENT_TIMESTAMP) BETWEEN @d1 AND
@d2-1
WHEN TRUE THEN 1 ELSE 0 END))) + '.' +
ltrim(str(SUM(CASE
DATEDIFF(day, statuschangedate, CURRENT_TIMESTAMP) BETWEEN @d2 AND
@d3-1
WHEN TRUE THEN 1 ELSE 0 END))) + '.' +
ltrim(str(SUM(CASE
DATEDIFF(day, statuschangedate, CURRENT_TIMESTAMP) BETWEEN @d3 AND
@d4-1
WHEN TRUE THEN 1 ELSE 0 END))) + '.' +
ltrim(str(SUM(CASE
DATEDIFF(day, statuschangedate, CURRENT_TIMESTAMP) BETWEEN @d4 AND
@d5-1
WHEN TRUE THEN 1 ELSE 0 END))) + '.' +
ltrim(str(SUM(CASE
DATEDIFF(day, statuschangedate, CURRENT_TIMESTAMP) >= @d5
WHEN TRUE THEN 1 ELSE 0 END))) + '.'
FROM prospects
WHERE CommunityCode = @CommCode
AND prospectstatus='L'
)
GO
[Back to original message]
|