November 14, 2005 at 5:29 pm
Hi all,
I am trying to write a store procedure to group total sales for certain agents. Some agents have sub-agents so I need to group them together, i.e. for agent 190000, I need to group all agents whose agent ID start with 19XXXX to this agent's total sale. But the Sql analyzer keeps complain about the bold part. I just don't know if there is an other way around.
Thank you.
Betty
Create Proc ProducerSubProducerSales @AgentCode varchar(15), @StartDate Datetime, @EndDate Datetime
As
Insert into temptSalesSummary
select @agentCode agentCode, orgname, '', count(order_total) TotalNumTrxns,
Cast(sum(Order_total)/100.00 As Decimal(12,2)) totalSales,
month(@startDate),
month(@EndDate),
year(@startDate),
year(@endDate),
@startdate,
@Enddate
from vs v join agentDetails D
on v.agentCode=d.agentID
Where
convert(char(10),txndatetime, 126) <= convert(char(10), @EndDate,126)
and convert(char(10),txndatetime, 126) >=convert(char(10), @StartDate,126)
and Select Case substring(@agentcode, 1, 2)
when '17' then v.agentCode like '17%'
When '19' then v.agentCode like '19%'
When '13' then v.agentCode like '13%'
End
order by sum(order_total) desc
Return
November 14, 2005 at 6:52 pm
try this :
change your case statement to
and v.agentCode like substring(@agentcode, 1, 2) + '%'
November 14, 2005 at 6:59 pm
Do only Agents with codes begining with 13, 17 and 19 have sub-agents? (or was this just an example?).
If all agents may have subagents, then this SQL comparison might be easier and also might support usage of an index on agent code:
where vs.agentcode like substring(@agentcode, 1, 2) + '%'
Date comparisons do not require a conversion to strings, so:
where convert(char(10),txndatetime, 126) =convert(char(10), @StartDate,126)
can more simply be:
where VS.txndatetime between @StartDate and @EndDate
Regarding "count(order_total)", this will provide a count of the different order_totals but if in table vs there are two identical order_totals, this would only be counted as one not as two. "count(*)" may be what you need.
Summing table VS as a seperate subquery would be clearer and also would not require to explictly list all of the non-aggregated columns within the group by:
Try this:
select @agentCode agentCode
, orgname
, ''
, AgentSales.TotalNumTrxns
, Cast(AgentSales.totalSales / 100.00 As Decimal(12,2)) As totalSales
, month(@startDate)
, month(@EndDate)
, year(@startDate)
, year(@endDate)
,@startdate
,@Enddate
from agentDetails
JOIN(select substring(vs.agentcode, 1, 2) as AgentCodePrefix
, count(*) AS TotalNumTrxns
, sum(Order_total as totalSales
from VS
-- This where condition may allow usage of an index
where vs.agentcode like substring(@agentcode, 1, 2) + '%' -- This may allow usage of an index
andVS.txndatetime between @StartDate and @EndDate
group by substring(vs.agentcode, 1, 2)
) AS AgentSales
-- value LIKE with leading constants may allow usage of an index
on agentDetails.agentcode like AgentSales.AgentCodePrefix + '%'
SQL = Scarcely Qualifies as a Language
November 14, 2005 at 7:14 pm
"count(order_total)" will count 2 identical values as 2, not 1.
It will not count rows where order_total IS NULL.
I believe idea of
where convert(char(10),txndatetime, 126) <= convert(char(10), @EndDate,126)
and convert(char(10),txndatetime, 126) >=convert(char(10), @StartDate,126)
was to compare dates excluding time part.
Proper way to do it:
SET @StartDate = convert(datetime, convert(int, @StartDate -0.5))
SET @EndDate = convert(datetime, convert(int, @EndDate -0.5)) + convert(datetime, '23:59:59.997'
-- This points @startDate to the start of the day, @EndDate to the end of the day
select ...
where VS.txndatetime between @StartDate and @EndDate
_____________
Code for TallyGenerator
November 15, 2005 at 10:34 am
Hi all,
Thanks all your input, this gets me very excited since this is my first post. I noticed that this is a very active forum. I will take a look at your replies.
The one above is just an example. But I forgot one thing, the first two characters of subagents' ID for certain group is not always the same as the master agent ID. i.e. The master AgentID 141333 actually has subagents with agentID start with 12XXXX. What should I do with this case?
Betty
November 15, 2005 at 11:11 am
Hi all,
The initial store procedure I want to write is: I need a list of agent sales during a certain period, from most to least. But among those agents, only several agents have subagents. The real case is:
Master Agent 190000 has subagent 19XXXX, so need group by 19XXXX
Master Agent 160000 has subagent 16XXXX, so need group by 16XXXX
Master Agent 131222 has subagent 17XXXX, so need group by 131222+17XXXX
all other agents group by itself.
I just don't know how I can write only a store procedure and get the result in one execution.
Any other idea will be very helpful.
Betty
November 15, 2005 at 12:49 pm
You must have the rule you've just described in table, not in code of SP.
After that you may use simple joins in SP, and rules may be added or changed without changing code.
_____________
Code for TallyGenerator
November 15, 2005 at 1:13 pm
Hi Sergiy,
How do I set up those rules in table. Can you give me an example?
Thanks.
Betty
November 15, 2005 at 1:41 pm
Something like this:
Code AgentCode
190000 19XXXX
160000 16XXXX
131222 131222
131222 17XXXX
But you know the rule better, you can do it more close to the real case.
_____________
Code for TallyGenerator
November 15, 2005 at 2:08 pm
Sergiy,
I think this's a great idea. The the way I understand you is as follow:
I can add one more column masterAgentID in the VS table besides the origianl agentID.
It will looks like this:
totalsales AgentID MasterAgentID
100.00 190000 190000
200.00 163457 160000
300.00 160000 160000
350.00 191234 190000
400.00 171222 131222
400.00 173333 131222
400.00 131222 131222
500.00 123456 123456
So later on, as long as I group sales by MasterAgentID, then I will solve all the cases, right
Thank you, thank you.
November 16, 2005 at 7:17 am
If the logic of determining the agents/subagents gets too complicated for the actual stored procedure, consider packaging it in a user-defined function which takes in a master agent ID and returns a table of the sub-agent IDs and then changing the part in the SP that currently says
and Select Case substring(@agentcode, 1, 2)
when '17' then v.agentCode like '17%'
When '19' then v.agentCode like '19%'
When '13' then v.agentCode like '13%'
End
to something like
and v.agentCode IN (SELECT agentCode FROM dbo.fnMyFunctionName(MasterAgentID))
I might be off on the SQL syntax here, but hopefully you get the idea. Ought to work...
November 16, 2005 at 10:07 am
Hi milzs,
That's another good way to do it. I will try it too.
Thank you.
Viewing 12 posts - 1 through 11 (of 11 total)
You must be logged in to reply to this topic. Login to reply