【问题标题】:Calculated SQL column in stored procedure存储过程中的计算 SQL 列
【发布时间】: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 - 如果accumulatedmass00:00 处为零,则同样的问题)
  • 您是否将date 存储在一列中而time 存储在另一列中?而不是将datetime 存储在一列中?嗯...在加入和减去 1 小时之前,将它们组合成正确的 datetime。啊。你正在这样做了。因此,只需从联接中删除日期比较即可。
  • @VladimirBaranov,无法删除它。计算根本不起作用。因为它必须获得前一个值和后一个值。

标签: sql sql-server-2008 stored-procedures sql-server-2008-r2


【解决方案1】:

简单更改:

left join CTE T3 on T1.OperationDate = T3.OperationDate and T1.MeasurementCode = T3.MeasurementCode and DATEADD(Hour, 1, T1.oDateTime)= T3.oDateTime

到:

left join CTE T3 on (T1.OperationDate = T3.OperationDate and T1.MeasurementCode = T3.MeasurementCode and DATEADD(Hour, 1, T1.oDateTime)= T3.oDateTime) or (dateadd(day, 1, T1.OperationDate) = T3.OperationDate and T1.MeasurementCode = T3.MeasurementCode and DATEADD(Hour, 1, T1.oDateTime)= T3.oDateTime)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 2016-09-01
    • 1970-01-01
    • 2010-09-15
    • 2010-09-18
    • 1970-01-01
    相关资源
    最近更新 更多