Topic: Stored Procedure Posted: 15 Jan 2014 at 5:47am
I have a CR that uses a stored procedure to generate its output. This works fine as is but, it needs to do more. It calculates a single value and I need this SPROC to calculate about 20 values. So, now to the question. How do, I implement the other 19 or so calculations ? How do, I call the other 19 SPROC In a stored procedure in CR ?
Here is a copy of the existing script. As, I mentioned another 19 or so scripts would be needed to calculate the other values. What is the basic structure to implement your suggestion?
/***** This script generates the ASSIGNED column. */
Select ws.P4DistrictNumber
as BranchNo, ws.Cycle
as Trip,
COUNT(DISTINCT msi.MeterSessionInputKey)as Assigned
from fcs.dbo.WorkSet
as ws
leftouterjoin fcs.dbo.Work
as w
on ws.WorkSetKey
= w.WorkSetKey
leftouterjoin fcs.dbo.Customer
as c
on w.WorkKey
= c.WorkKey
leftouterjoin fcs.dbo.WorkAssignment
as wa
on ws.WorkSetID
= wa.WorkSetID
leftouterjoin fcs.dbo.meter
as m
on c.CustomerKey
= m.CustomerKey
leftouterjoin fcs.dbo.CustomDatafield
as cdf
on c.CustomerKey
= cdf.CustomerKey
leftouterjoin fcs.dbo.CustomDataField
as cdfl
on m.MeterKey
= cdfl.MeterKey
leftouterjoin fcs.dbo.MeterSessionInput
as msi
on m.MeterKey
= msi.MeterKey
leftouterjoin fcs.dbo.MeterSessionOutput
as mso
on msi.MeterSessionInputKey
= mso.MeterSessionInputKey
Joined: 20 Nov 2006
Online Status: Offline
Posts: 3701
Posted: 15 Jan 2014 at 6:49am
I don't know enough about your database to give you an exact answer, but you might try something like this:
Select
'Assigned' as CalcType,
ws.P4DistrictNumber as BranchNo,
ws.Cycle as Trip,
COUNT(DISTINCT msi.MeterSessionInputKey) as Value
from ...
UNION
Select
'<name of the second value>' as CalcType,
ws.P4DistrictNumber as BranchNo,
ws.Cycle as Trip,
<whatever the summary is for the second calculation> as Value
from ...
UNION
Select
'<name of the third value>' as CalcType,
ws.P4DistrictNumber as BranchNo,
ws.Cycle as Trip,
<whatever the summary is for the third calculation> as Value
from ...
etc. until you have all 19 values
This will give you a result set that has 19 rows, each with a "CalcType" field indicating what type of value it is and a "Value" field that has the actual number in it.
If you need it all in a single row, I can get you the logic for that as well.
Thanks for this suggestion. I tried it by taking the same code and putting a UNION between the code but got an error message:
Msg 156, Level 15, State 1, Line 48 Incorrect syntax near the keyword 'UNION'.
If this can be fixed all, I would have to do is add the other sproc after a UNION as you did in your example to make it work. Please see my code below.
Select ws.P4DistrictNumber as BranchNo, ws.Cycle as Trip, COUNT(DISTINCT msi.MeterSessionInputKey) as Assigned from fcs.dbo.WorkSet as ws
left outer join fcs.dbo.Work as w on ws.WorkSetKey = w.WorkSetKey
left outer join fcs.dbo.Customer as c on w.WorkKey = c.WorkKey
left outer join fcs.dbo.WorkAssignment as wa on ws.WorkSetID = wa.WorkSetID
left outer join fcs.dbo.meter as m on c.CustomerKey = m.CustomerKey
left outer join fcs.dbo.CustomDatafield as cdf on c.CustomerKey = cdf.CustomerKey
left outer join fcs.dbo.CustomDataField as cdfl on m.MeterKey = cdfl.MeterKey
left outer join fcs.dbo.MeterSessionInput as msi on m.MeterKey = msi.MeterKey
left outer join fcs.dbo.MeterSessionOutput as mso on msi.MeterSessionInputKey = mso.MeterSessionInputKey
where ws.StartDateTime IS NOT NULL and wa.RetiredFlag = 0 and wa.LoadStatusIndicator NOT IN (0, 4) and msi.P4UtilityTypeReadIndicator != 'F' and
case when cast(wa.startdatetime as date) <= cast(ws.scheduledreaddate as date) and wa.workfiltername not in ('DNRs','Type 2s/3s') or ((ws.worksetid %100 < 50 and substring(ws.worksetid, len(ws.worksetid) - 3, 1) = 0)) then 1 End = 1 and ws.Cycle = 7
group by ws.P4DistrictNumber, ws.Cycle
order by ws.P4DistrictNumber
UNION
/***** This script generates the ASSIGNED column. */ Select ws.P4DistrictNumber as BranchNo, ws.Cycle as Trip, COUNT(DISTINCT msi.MeterSessionInputKey) as Assigned
from fcs.dbo.WorkSet as ws
left outer join fcs.dbo.Work as w on ws.WorkSetKey = w.WorkSetKey
left outer join fcs.dbo.Customer as c on w.WorkKey = c.WorkKey
left outer join fcs.dbo.WorkAssignment as wa on ws.WorkSetID = wa.WorkSetID
left outer join fcs.dbo.meter as m on c.CustomerKey = m.CustomerKey
left outer join fcs.dbo.CustomDatafield as cdf on c.CustomerKey = cdf.CustomerKey
left outer join fcs.dbo.CustomDataField as cdfl on m.MeterKey = cdfl.MeterKey
left outer join fcs.dbo.MeterSessionInput as msi on m.MeterKey = msi.MeterKey
left outer join fcs.dbo.MeterSessionOutput as mso on msi.MeterSessionInputKey = mso.MeterSessionInputKey
where ws.StartDateTime IS NOT NULL and wa.RetiredFlag = 0 and wa.LoadStatusIndicator NOT IN (0, 4) and msi.P4UtilityTypeReadIndicator != 'F' and
case when cast(wa.startdatetime as date) <= cast(ws.scheduledreaddate as date) and wa.workfiltername not in ('DNRs','Type 2s/3s') or ((ws.worksetid %100 < 50 and substring(ws.worksetid, len(ws.worksetid) - 3, 1) = 0)) then 1 End = 1 and
Joined: 20 Nov 2006
Online Status: Offline
Posts: 3701
Posted: 16 Jan 2014 at 2:58am
Take the Order By out of the first part of the query - Order By with a Union will apply to the whole result set, so you can't have it in each query. What I usually do is use parentheses around the query and then use the field number instead of the field name. It looks something like this:
Dell thanks for all your help in this matter. I am so accustom to using tools that generate code that I need an sql refresher course. Which leads to two follow up questions. The code correction you suggested worked fine but I expected the expression to be in columns. Instead, I got value 1, then value 2 and I expect if I add the other18 or so expressions they will be rows instead of columns. First, is there a way of making them columns? Second, several of the expressions are actually part of a single expression. What, I mean is ExpA + ExpB = TotalExp instead of adding these up manually after the script is run is there a way to have the script sum the two parts and export the total?
Joined: 20 Nov 2006
Online Status: Offline
Posts: 3701
Posted: 16 Jan 2014 at 8:34am
Yes, to both parts of your question.
To get them all in one row, do something like the following:
Select
BranchNo,
Trip,
sum(Value1) as Value1,
sum(Value2) as Value2,
...
--Here's how to get the calc from your second question.
sum(Value5) + sum(Value6) as TotalValue,
...
sum(Value19) as Value19
from (
Select
ws.P4DistrictNumber as BranchNo,
ws.Cycle as Trip,
COUNT(DISTINCT msi.MeterSessionInputKey) as Value1,
0 as Value2,
0 as Value3,
...
0 as Value19
from fcs.dbo.WorkSet as ws
...
UNION
Select
ws.P4DistrictNumber as BranchNo,
ws.Cycle as Trip,
0 as Value1,
COUNT(field2) as Value2,
0 as Value3,
...
0 as Value19
from fcs.dbo.WorkSet as ws
...
UNION
Select
ws.P4DistrictNumber as BranchNo,
ws.Cycle as Trip,
0 as Value1,
0 as Value2,
COUNT(field3) as Value3,
...
0 as Value19
from fcs.dbo.WorkSet as ws
...
) as Data
Group By BranchNo, Trip
Dell, I am not following what you mean. Here is the script that produced the output. Should, I put the first select statement along with the four fields listed below over the attached script? With regard to the second question each block of code that is joined by a Union is doing one of the calculations that belong to the Exp1 + Exp2 = ExpTot so, I don't understand how one of the calculations can be referenced outside of the scope where it is being calculated.
/***** This script generates the ASSIGNED column. */ ( Select ws.P4DistrictNumber as BranchNo, ws.Cycle as Trip, COUNT(DISTINCT msi.MeterSessionInputKey) as Assigned
from fcs.dbo.WorkSet as ws
left outer join fcs.dbo.Work as w on ws.WorkSetKey = w.WorkSetKey
left outer join fcs.dbo.Customer as c on w.WorkKey = c.WorkKey
left outer join fcs.dbo.WorkAssignment as wa on ws.WorkSetID = wa.WorkSetID
left outer join fcs.dbo.meter as m on c.CustomerKey = m.CustomerKey
left outer join fcs.dbo.CustomDatafield as cdf on c.CustomerKey = cdf.CustomerKey
left outer join fcs.dbo.CustomDataField as cdfl on m.MeterKey = cdfl.MeterKey
left outer join fcs.dbo.MeterSessionInput as msi on m.MeterKey = msi.MeterKey
left outer join fcs.dbo.MeterSessionOutput as mso on msi.MeterSessionInputKey = mso.MeterSessionInputKey
where ws.StartDateTime IS NOT NULL and wa.RetiredFlag = 0 and wa.LoadStatusIndicator NOT IN (0, 4) and msi.P4UtilityTypeReadIndicator != 'F' and
case when cast(wa.startdatetime as date) <= cast(ws.scheduledreaddate as date) and wa.workfiltername not in ('DNRs','Type 2s/3s') or ((ws.worksetid %100 < 50 and substring(ws.worksetid, len(ws.worksetid) - 3, 1) = 0)) then 1 End = 1 and
ws.Cycle = 8
group by ws.P4DistrictNumber, ws.Cycle
UNION
/***** This script generates the ReadRICS column. */ Select ws.P4DistrictNumber as BranchNo, ws.Cycle as Trip, COUNT(DISTINCT mso.MeterSessionOutputKey) as ReadsTotByRte
from fcs.dbo.WorkSet as ws
left outer join fcs.dbo.Work as w on ws.WorkSetKey = w.WorkSetKey
left outer join fcs.dbo.Customer as c on w.WorkKey = c.WorkKey
left outer join fcs.dbo.WorkAssignment as wa on ws.WorkSetKey = wa.WorkSetKey
left outer join fcs.dbo.meter as m on c.CustomerKey = m.CustomerKey
left outer join fcs.dbo.CustomDatafield as cdf on c.CustomerKey = cdf.CustomerKey
left outer join fcs.dbo.CustomDataField as cdfl on m.MeterKey = cdfl.MeterKey
left outer join fcs.dbo.MeterSessionInput as msi on m.MeterKey = msi.MeterKey
left outer join fcs.dbo.MeterSessionOutput as mso on msi.MeterSessionInputKey = mso.MeterSessionInputKey
where ws.StartDateTime IS NOT NULL and wa.RetiredFlag = 0 and wa.LoadStatusIndicator NOT IN (0, 4) and msi.P4UtilityTypeReadIndicator != 'F' and
mso.ReadCode NOT IN ('0','2' ,'99') and mso.BestResultIndicator = 2 and (cdf.CustomData IS NULL or lower(substring(cdf.customdata, 9, 4)) != 'demo') and ( mso.TroubleCode1 <> 'CA' and mso.TroubleCode2 <> 'CA' and mso.TroubleCode3 <> 'CA' and mso.TroubleCode4 <> 'CA' and mso.TroubleCode5 <> 'CA' and mso.TroubleCode6 <> 'CA' ) and
case when cast(wa.startdatetime as date) <= cast(ws.scheduledreaddate as date) and wa.workfiltername not in ('DNRs','Type 2s/3s') or ((ws.worksetid %100 < 50 and substring(ws.worksetid, len(ws.worksetid) - 3, 1) = 0)) then 1 End = 1 and
Joined: 20 Nov 2006
Online Status: Offline
Posts: 3701
Posted: 16 Jan 2014 at 11:47am
Try this:
Select
BranchNo, trip,
sum(Assigned) as Assigned,
sum(ReadsTotByRte) as ReadsTotByRte
from
(
Select
ws.P4DistrictNumber as BranchNo,
ws.Cycle as Trip,
COUNT(DISTINCT msi.MeterSessionInputKey) as Assigned,
0 as ReadsTotByRte
from fcs.dbo.WorkSet as ws
left outer join fcs.dbo.Work as w
on ws.WorkSetKey = w.WorkSetKey
left outer join fcs.dbo.Customer as c
on w.WorkKey = c.WorkKey
left outer join fcs.dbo.WorkAssignment as wa
on ws.WorkSetID = wa.WorkSetID
left outer join fcs.dbo.meter as m
on c.CustomerKey = m.CustomerKey
left outer join fcs.dbo.CustomDatafield as cdf
on c.CustomerKey = cdf.CustomerKey
left outer join fcs.dbo.CustomDataField as cdfl
on m.MeterKey = cdfl.MeterKey
left outer join fcs.dbo.MeterSessionInput as msi
on m.MeterKey = msi.MeterKey
left outer join fcs.dbo.MeterSessionOutput as mso
on msi.MeterSessionInputKey = mso.MeterSessionInputKey
where
ws.StartDateTime IS NOT NULL and
wa.RetiredFlag = 0 and
wa.LoadStatusIndicator NOT IN (0, 4) and
msi.P4UtilityTypeReadIndicator != 'F' and
case
when
cast(wa.startdatetime as date) <= cast(ws.scheduledreaddate as date) and
wa.workfiltername not in ('DNRs','Type 2s/3s') or
((ws.worksetid %100 < 50 and
substring(ws.worksetid, len(ws.worksetid) - 3, 1) = 0))
then 1
End = 1 and
ws.Cycle = 8
group by ws.P4DistrictNumber, ws.Cycle
UNION
/***** This script generates the ReadRICS column. */
Select
ws.P4DistrictNumber as BranchNo,
ws.Cycle as Trip,
0 as Assigned,
COUNT(DISTINCT mso.MeterSessionOutputKey) as ReadsTotByRte
from fcs.dbo.WorkSet as ws
left outer join fcs.dbo.Work as w
on ws.WorkSetKey = w.WorkSetKey
left outer join fcs.dbo.Customer as c
on w.WorkKey = c.WorkKey
left outer join fcs.dbo.WorkAssignment as wa
on ws.WorkSetKey = wa.WorkSetKey
left outer join fcs.dbo.meter as m
on c.CustomerKey = m.CustomerKey
left outer join fcs.dbo.CustomDatafield as cdf
on c.CustomerKey = cdf.CustomerKey
left outer join fcs.dbo.CustomDataField as cdfl
on m.MeterKey = cdfl.MeterKey
left outer join fcs.dbo.MeterSessionInput as msi
on m.MeterKey = msi.MeterKey
left outer join fcs.dbo.MeterSessionOutput as mso
on msi.MeterSessionInputKey = mso.MeterSessionInputKey
where
ws.StartDateTime IS NOT NULL and
wa.RetiredFlag = 0 and
wa.LoadStatusIndicator NOT IN (0, 4) and
msi.P4UtilityTypeReadIndicator != 'F' and
mso.ReadCode NOT IN ('0','2' ,'99') and
mso.BestResultIndicator = 2 and
(cdf.CustomData IS NULL or
lower(substring(cdf.customdata, 9, 4)) != 'demo') and
(
mso.TroubleCode1 <> 'CA' and
mso.TroubleCode2 <> 'CA' and
mso.TroubleCode3 <> 'CA' and
mso.TroubleCode4 <> 'CA' and
mso.TroubleCode5 <> 'CA' and
mso.TroubleCode6 <> 'CA'
) and
case
when cast(wa.startdatetime as date) <= cast(ws.scheduledreaddate as date) and
wa.workfiltername not in ('DNRs','Type 2s/3s') or
((ws.worksetid %100 < 50 and
substring(ws.worksetid, len(ws.worksetid) - 3, 1) = 0))
then 1
End = 1 and
ws.Cycle = 8
group by ws.P4DistrictNumber, ws.Cycle
) as Data
group by BranchNo
order by BranchNo
This will get you the branch number, trip, and then two numeric fields - Assigned and ReadsTotByRte. The trick to this technique is that every query in your union statement will have as many "measure" fields as you need for ALL of the totals. However, each query will only set the total for its own field and then set 0 for all of the other "measure" fields. By wrapping that in an outer select statement and then summing each field, you get a single record for each branch/trip that contains all of the summaries (value from each of the "measure" fields) for that branch/trip combination.
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot delete your posts in this forum You cannot edit your posts in this forum You cannot create polls in this forum You cannot vote in polls in this forum