【发布时间】:2015-04-29 17:10:08
【问题描述】:
我有以下存储过程:
SELECT
a.OtherMeasurementID
, a.MeasurementID
, b.MeasurementCode
, a.OperationDate
, a.OperationTime
, a.AccumulatedMass
, CAST(a.OperationDate AS datetime) + CAST(a.OperationTime as datetime) oDateTime
INTO
#_OtherMeasurement
FROM
_OtherMeasurement a
INNER JOIN
_Measurement b ON a.MeasurementID = b.MeasurementID
WHERE
a.OperationDate >= DATEADD(DAY, -1, @StartDate)
AND a.OperationDate <= DATEADD(DAY, 1, @EndDate)
AND b.MeasurementCode LIKE '%Inlet%'
--============================================
;with CTE as
(
select
T1.OtherMeasurementID
, t1.MeasurementID
, T1.MeasurementCode
, T1.OperationDate
, T1.OperationTime
, T1.AccumulatedMass
, case when T1.AccumulatedMass = 0 then 0 else T1.AccumulatedMass - T2.AccumulatedMass end as ReceivedMass
, T1.oDateTime
From
#_OtherMeasurement T1
left join
#_OtherMeasurement T2 on T1.MeasurementCode = T2.MeasurementCode
and DATEADD(Hour, -1, T1.oDateTime) = T2.oDateTime
left join
#_OtherMeasurement T3 on T1.MeasurementCode = T3.MeasurementCode
and DATEADD(Hour, 1, T1.oDateTime)= T3.oDateTime
)
,CTE2 as
(
select
T1.OtherMeasurementID
, T1.MeasurementID
, T1.MeasurementCode
, T1.OperationDate
, T1.OperationTime
, T1.AccumulatedMass
, case when T1.AccumulatedMass = 0 then (T2.ReceivedMass + T3.ReceivedMass)/2 else T1.ReceivedMass end as ReceivedMass
From
CTE T1
left join
CTE T2 on T1.OperationDate = T2.OperationDate and T1.MeasurementCode = T2.MeasurementCode
and DATEADD(Hour, -1, T1.oDateTime)= T2.oDateTime
left join
CTE T3 on T1.OperationDate = T3.OperationDate and T1.MeasurementCode = T3.MeasurementCode
and DATEADD(Hour, 1, T1.oDateTime)= T3.oDateTime
)
select
OtherMeasurementID,
MeasurementID,
MeasurementCode,
OperationDate,
OperationTime,
AccumulatedMass,
coalesce(ReceivedMass, 0) ReceivedMass
from
CTE2
WHERE
OperationDate BETWEEN @StartDate AND @EndDate
如果你在 CTE2 上看到,有一条线
case when T1.AccumulatedMass = 0 then (T2.ReceivedMass + T3.ReceivedMass)/2 else T1.ReceivedMass end as ReceivedMass
如果同一日期的累积质量为零,则该行将起作用。该表的数据以小时为基础。如果零值在 10/Jan/2015 23:00:00 上,则该行将不起作用。因为下一个值应该是 11/Jan/2015 00:00:00。示例语句是,如果零之前和之后的值在同一日期,则计算将起作用。如果没有,那么将无法正常工作。
我的问题是,即使零之后的下一个值在不同的日期,我怎样才能使公式起作用..?
示例:
OtherMeasurementID MeasurementID MeasurementCode OperationDate OperationTime AccumulatedMass ReceivedMass
17 1 Water Inlet 13-Oct-2014 17:00:00 236265.36 518.58
18 1 Water Inlet 13-Oct-2014 18:00:00 236795.95 530.59
19 1 Water Inlet 13-Oct-2014 19:00:00 0 533.57
20 1 Water Inlet 13-Oct-2014 20:00:00 237865.13 536.55
21 1 Water Inlet 13-Oct-2014 21:00:00 238404.14 539.01
22 1 Water Inlet 13-Oct-2014 22:00:00 238944.05 539.91
23 1 Water Inlet 13-Oct-2014 23:00:00 0 0
24 1 Water Inlet 14-Oct-2014 0:00:00 240026 240026
25 1 Water Inlet 14-Oct-2014 1:00:00 240566.98 540.98
26 1 Water Inlet 14-Oct-2014 2:00:00 241107.92 540.94
如果您可以在上面的示例中看到。在 2015 年 10 月 13 日 19:00,累积质量为零。所以计算接收质量的公式是(previous receivedmass before zero + next receivedmass after zero) / 2
但是,如果您看到 2015 年 10 月 13 日 23:00,则上面的公式不起作用,因为 next receivedmass after zero 是另一个日期,即 2015 年 10 月 14 日 00:00。
谢谢。
【问题讨论】:
-
您能否尝试将查询简化为仅处理手头问题的查询(即我希望
CTE暂时可以替换为表变量)并带有一些示例数据和预期结果。目前,有很多查询需要我们理解,我们 a) 无权访问您的数据库,b) 不知道您想要实现什么。 -
@Damien_The_Unbeliever,已添加。
-
您正在加入
T1.OperationDate = T3.OperationDate,因此您将其限制在同一天。如果从join中删除这部分会发生什么? (并删除T1.OperationDate = T2.OperationDate- 如果accumulatedmass在00:00处为零,则同样的问题) -
您是否将
date存储在一列中而time存储在另一列中?而不是将datetime存储在一列中?嗯...在加入和减去 1 小时之前,将它们组合成正确的datetime。啊。你正在这样做了。因此,只需从联接中删除日期比较即可。 -
@VladimirBaranov,无法删除它。计算根本不起作用。因为它必须获得前一个值和后一个值。
标签: sql sql-server-2008 stored-procedures sql-server-2008-r2