【发布时间】:2017-08-04 03:38:38
【问题描述】:
我需要扩展现有的存储过程(即,基于旧存储过程创建一个新的 SP)以包含一些额外的计算数据。需要四个额外的列来提供从 SP 的结果生成的报告:
简而言之,报告显示 MonthlySales,另外四个列填充了基于该行中指定的“Unit”的 Category.Subcategory 值的货币值(每个 Unit 在结果集中都有自己的行和报告)。
新列是四个类别:New.New、New.Assumed、Existing.Existing 和 Existing.Organic
因此,结果集中的每一行都包含单个 Unit 的数据,并且该 Unit 属于所报告时间段的 Category.Subcategory 值之一(IOW,这四个包中只有一个在每个包上都有一个值行)。
检索此数据涉及三个表:
MasterUnitProjSales,每个 Unit 都有一个“NewBiz”标志(如果为真,它属于两个值的“New”系列;否则,它属于两个值的“Existing”系列值;因此,Category.Subcategory 值的 Category 部分可以由该值确定)。
ReportingMonthlySales,每个 Unit/MemberNo 都有一个 MonthlySales(Money)字段,以及 Year 和 Month 数据。
CustomerCategoryLog,其中包含 Unit/MemberNo 对、Category 和 Subcategory 字段以及 BeginDate 和 EndDate 字段,用于记录 Unit/Member 所处的 Subcategory.Category开始/结束时间范围。
旧版 SP 的工作方式是将一年的数据存储到临时表中,然后将前一年的数据存储到第二个临时表中,然后将它们组合起来,然后返回。
有了这个额外的皱纹,我的想法(伪SQL,我不是[T]-SQL-head)是:
(“CombinedYears”是前两个临时表“CurrentYear”和“PriorYear”的合并表)
Select * from #CombinedYears CY,
NewNew = select MonthlySales from ReportingMonthlySales RMS where Category = 'New' and Subcategory = 'New' and
RMS.Unit = CY.Unit
left join CustomerCategoryLog CCL on RMS.Unit = CCL.Unit,
NewAssumed = select MonthlySales from ReportingMonthlySales RMS where Category = 'New' and Subcategory = 'Assumed' and
RMS.Unit = CY.Unit
left join CustomerCategoryLog CCL on RMS.Unit = CCL.Unit,
ExistingExisting = select MonthlySales from ReportingMonthlySales RMS where Category = 'Existing' and Subcategory = 'Existing' and
RMS.Unit = CY.Unit
left join CustomerCategoryLog CCL on RMS.Unit = CCL.Unit,
ExistingOrganic = select MonthlySales from ReportingMonthlySales RMS where Category = 'Existing' and Subcategory = 'Organic' and
RMS.Unit = CY.Unit
left join CustomerCategoryLog CCL on RMS.Unit = CCL.Unit
我知道这是错误的、笨拙的和笨拙的,但也许它可以帮助您理解表格之间的联系等。
注意:这个问题与我的问题 here 部分相关,但就提供上下文或背景信息而言,这可能没有帮助。
更新
我尝试了 Charles Bretana 的想法,但不得不对其进行调整以使其能够在 LINQPad 中“编译”。关于表格的确切性质,我可能误导了您。我将在下面包含它们,然后显示我在 LINQPad 中尝试的更改后的查询。
CustomerCategoryLog
-------------------
MemberNo (VarChar)
Unit (VarChar)
Custno (VarChar)
Category (VarChar)
Subcategory (VarChar)
BeginDate (DateTime)
EndDate (DateTime)
ChangedBy (VarChar)
ChangedOn (DateTime)
MasterUnitProjSales
-------------------
Unit (VarChar)
CYear (Int)
CSDirector (VarChar)
ProjectedSales (Money)
NewBiz (Int)
Category (VarChar) <= this is not directly connected to the "Category" I need, and should be ignored
Segment (VarChar)
ReportingMonthlySales
---------------------
AutoID (Int)
Unit (VarChar)
MemberNo (VarChar)
NumUnits (Int)
MonthlySales (Money)
CYear (Int)
Cmonth (Int)
CreateDate (DateTime)
以下内容(由我修改,但基于 Bretana 的)试图在 LINQPad 中生成一些数据,但需要“永远”:
DECLARE @CYear INT
SET @CYear = 2016
DECLARE @Cmonth INT
SET @Cmonth = 4
Select CSDirector,
Category,
Segment,
r1.unit,
NumUnits=isnull((Select sum(NumUnits) from ReportingMonthlySales where unit=r1.unit and cyear=r1.cyear and
cmonth = @Cmonth),0),
MonthSales=isnull((Select sum(MonthlySales) from ReportingMonthlySales where unit=r1.unit and cyear=r1.cyear
and cmonth = @Cmonth),0.00),
YTDSales = (Select sum(MonthlySales) From ReportingMonthlySales where unit=r1.unit and cyear=r1.cyear and
cmonth <= @Cmonth),
ProjSales = (Select ProjectedSales from MasterUnitsProjSales where UNit = r1.Unit and Cyear=r1.cyear),
YTDProjSales = (Select ProjectedSales from MasterUnitsProjSales where UNit = r1.Unit and Cyear=r1.cyear) / 12
* @Cmonth,
YTDBudgetPerc = (Select sum(MonthlySales) From ReportingMonthlySales where unit=r1.unit and cyear=r1.cyear
and cmonth <= @Cmonth) /
case when (Select ProjectedSales from MasterUnitsProjSales where UNit = r1.Unit and Cyear=r1.cyear) =
0 then 1 else ((Select ProjectedSales from MasterUnitsProjSales where UNit = r1.Unit and Cyear=r1.cyear) / 12 * @Cmonth) end
into #CombinedYears2
From MasterUnitsProjSales r1
where r1.Cyear=@CYear
order by r1.NewBiz,r1.Unit
Select cy.*,
rms.MonthlySales newnew,
rms.MonthlySales NewAssumed,
rms.MonthlySales ExistingExisting,
rms.MonthlySales ExistingOrganic
from #CombinedYears2 CY
left join ReportingMonthlySales rms
on rms.Unit = cy.Unit
join CustomerCategoryLog n
on n.Category = 'New'
and n.Subcategory = 'New'
and n.Unit = cy.Unit
left join CustomerCategoryLog a
on a.Category = 'New'
and a.Subcategory = 'Assumed'
and a.Unit = CY.Unit
left join CustomerCategoryLog e
on e.Category = 'Existing'
and e.Subcategory = 'Existing'
and e.Unit = CY.Unit
left join CustomerCategoryLog o
on o.Category = 'Existing'
and o.Subcategory = 'Organic'
and o.Unit = CY.Unit
更新 2
在处理完其他事情/把它放在一边,然后回到它并重新攻击它,这是我的新伪sql:
DECLARE @Unit varchar(30);
DECLARE @Year Int;
DECLARE @Month Int;
SELECT MonthlySales
INTO #NewSales
FROM ReportingMonthlySales RMS
JOIN CustomerCategoryLog CCL ON RMS.Unit = CCL.Unit
WHERE RMS.Unit = @Unit AND RMS.CYear = @Year AND RMS.Cmonth = @Month AND CCL.Subcategory = 'New'
SELECT MonthlySales
INTO #AssumedSales
FROM ReportingMonthlySales RMS
JOIN CustomerCategoryLog CCL ON RMS.Unit = CCL.Unit
WHERE RMS.Unit = @Unit AND RMS.CYear = @Year AND RMS.Cmonth = @Month AND CCL.Subcategory = 'Assumed'
SELECT MonthlySales
INTO #ExistingSales
FROM ReportingMonthlySales RMS
JOIN CustomerCategoryLog CCL ON RMS.Unit = CCL.Unit
WHERE RMS.Unit = @Unit AND RMS.CYear = @Year AND RMS.Cmonth = @Month AND CCL.Subcategory = 'Existing'
SELECT MonthlySales
INTO #OrganicSales
FROM ReportingMonthlySales RMS
JOIN CustomerCategoryLog CCL ON RMS.Unit = CCL.Unit
WHERE RMS.Unit = @Unit AND RMS.CYear = @Year AND RMS.Cmonth = @Month AND CCL.Subcategory = 'Organic'
将这四个临时表合二为一,将 MonthlySales 放入适当的 Category.Subcategory 列,并将其作为结果集返回以用于生成报告。
【问题讨论】:
-
我将尽快(明天)奖励这个; “引起注意”或“奖励现有答案”取决于从现在到那时的活动。
-
你的问题是什么?在编写计算所需内容的 SQL 查询时是否需要帮助?在这种情况下,请向我们提供样本数据和预期结果。或者您是否需要一种方法来“扩展”现有的遗留存储过程而不触及/更改它?在这种情况下解释为什么你不能改变它。
-
是的,我需要查询方面的帮助。正如我在更新中所指出的那样,在 Bretana 的回答中证明了下面的那个可能有效,但它需要“永远”才能运行。
标签: sql-server tsql stored-procedures calculated-columns