我有3个表格Site,Price和PriceMonth。网站有很多价格(在siteId上加入)。 PriceMonth持有一个由Price查询的日期(加入PriceMonth)。
我们的想法是,在将网站创建为占位符时创建价格记录。
当用户点击视图中的价格行时 - 我需要仅更新该年剩余时间的价格,并且仅从该月开始。
我已经为存储过程编写了代码。请暂时忽略硬编码值。它有效但可以更简单,更有效吗?
代码:
DECLARE @startDate smallDateTime
DECLARE @roc decimal(5,2)
DECLARE @Lec decimal(5,2)
DECLARE @power decimal(5,2)
SET @roc = (SELECT roc FROM [Price] WHERE siteId = 77 AND PriceMonthId = 527)
SET @lec = (SELECT lec FROM [Price] WHERE siteId = 77 AND PriceMonthId = 527)
SET @power = (SELECT [power] FROM [Price] WHERE siteId = 77 AND PriceMonthId = 527)
SET @startDate = (Select [month] FROM [PriceMonth] WHERE PriceMonthId = 527)
UPDATE
Price
SET
roc = @roc
, lec = @lec
, [power] = @power
FROM
Price
INNER JOIN priceMonth pm ON price.priceMonthId = pm.priceMonthId
WHERE
(DATEPART(mm,pm.[Month]) > DATEPART(mm,@startDate) AND
(DATEPART(yy,pm.[Month]) = DATEPART(yy,@startDate))) AND
price.SiteId = 77
答案 0 :(得分:1)
您可以将变量作为联接添加到查询中,如下所示:
UPDATE p
SET roc = sourcePrice.roc,
lec = sourcePrice.lec,
[power] = sourcePrice.[power]
FROM Price p
INNER JOIN [Price] sourcePrice
on p.siteId = sourcePrice.siteId
and sourcePrice.siteId = 527
INNER JOIN priceMonth pm
ON price.priceMonthId = pm.priceMonthId
INNER JOIN priceMonth sourcepm
ON sourcepm.PriceMonthId = 527
WHERE pm.[Month] > sourcepm.StartDate
AND (DATEPART(yy,pm.[Month]) = DATEPART(yy,sourcepm.StartDate)))
AND price.SiteId = 77
另请注意,我已从您的某个日期比较中删除了该函数 - 这样SQL Server可以使用可能在其上定义的任何索引来至少缩小值的范围。
答案 1 :(得分:0)
您可以使用多个赋值来设置多个变量和一个查询的结果。
SELECT top 1
@roc = roc,
@lec = lec,
@power = power
FROM Price
WHERE siteId = 77 and pricemonthid = 527
注意这种技巧:
您可以预先计算要更新的日期范围。这可能允许日期索引有用。
DECLARE @StartRange datetime, @EndRange datetime
SET @StartRange = DateAdd(mm, DateDiff(mm, @startDate, 0), 0)
SET @EndRange = DateAdd(yy, 1 + DateDiff(yy, @StartRange, 0), 0)
UPDATE...
WHERE @StartRange <= pm.Month AND pm.Month < @EndRange
AND price.SiteId = 77
答案 2 :(得分:0)
关于占位符的要求,您始终可以使用LEFT JOIN和COALESCE来回退到上个月的价格。或者,安排任务以创建每个月最后一天午夜的上个月的新月价格。