2

我有以下代码

SELECT MRT.sno, MRT.TypeName, MR.Adate, MAX(MRD.Value) AS Value
FROM MeterReadings MR 
INNER JOIN MeterReadingDetails MRD ON MRD.ReadingId = MR.sno
INNER JOIN MeterReadingTypes MRT ON MRT.sno = MRD.ReadingTypeId
WHERE MRT.sno IN (7,10,11)
GROUP BY MRT.sno,MRT.TypeName,MR.Adate
ORDER BY MR.Adate DESC

结果

sno TypeName                Adate                   Value

11  Toplam Kapasitif        2013-01-04 00:00:00     33,313
7   Toplam                  2013-01-04 00:00:00     7819,33
10  Toplam Reaktif          2013-01-04 00:00:00     640,492
11  Toplam Kapasitif        2013-01-03 00:00:00     33,276
7   Toplam                  2013-01-03 00:00:00     7805,934
10  Toplam Reaktif          2013-01-03 00:00:00     639,862

我想要一个名为“OldValue”的附加列。OldValue 列显示前一天的值,如下所示(上例的最后三行)

33,276
7805,934
639,862
null
null
null

我怎样才能做到这一点?可能有一个类似的例子来告诉我方法。

提前致谢...

更新

事实上,我写了这样的东西

SELECT MRT.sno, MRT.TypeName, MR.Adate, MAX(MRD.Value) AS Value, 

(SELECT Value From
    (SELECT TOP 1 XMR.Adate,XMRD.ReadingTypeId,MAX(XMRD.Value) AS Value 
    FROM MeterReadings XMR,MeterReadingDetails XMRD 
    WHERE XMRD.ReadingId = XMR.sno AND XMRD.ReadingTypeId = MRT.sno AND XMR.Adate<MR.Adate 
    GROUP BY XMR.Adate,XMRD.ReadingTypeId 
    ORDER BY XMR.Adate DESC) AS TBL
) AS OldValue

FROM MeterReadings MR 
INNER JOIN MeterReadingDetails MRD ON MRD.ReadingId = MR.sno
INNER JOIN MeterReadingTypes MRT ON MRT.sno = MRD.ReadingTypeId
WHERE MRT.sno IN (7,10,11)
GROUP BY MRT.sno,MRT.TypeName,MR.Adate

但我不知道,这是最好的方法吗?

4

1 回答 1

1

如果您使用的是 SQL Server 2012,则可以使用新的LAG分析功能

SQL Server 2012 引入了新的分析函数 LEAD() 和 LAG()。此函数在不使用自连接的情况下访问同一结果集中的后续行(用于领先)和上一行(用于滞后)的数据。

你的陈述然后变成

SELECT  *, LAG(Value) OVER (PARTITION BY sno ORDER BY Adate DESC)
FROM    (
          SELECT  MRT.sno, MRT.TypeName, MR.Adate, MAX(MRD.Value) AS Value, 
          FROM    MeterReadings MR 
                  INNER JOIN MeterReadingDetails MRD ON MRD.ReadingId = MR.sno
                  INNER JOIN MeterReadingTypes MRT ON MRT.sno = MRD.ReadingTypeId
          WHERE   MRT.sno IN (7,10,11)
          GROUP BY
                  MRT.sno,MRT.TypeName,MR.Adate
        ) q
ORDER BY
        Adate DESC

使用 SQL Server 2005/2008,我会将语句编写为

;WITH q AS (
  SELECT  MRT.sno, MRT.TypeName, MR.Adate, MAX(MRD.Value) AS Value, rn = ROW_NUMBER() OVER (PARTITION BY MRT.sno ORDER BY MR.Adate DESC)
  FROM    MeterReadings MR 
          INNER JOIN MeterReadingDetails MRD ON MRD.ReadingId = MR.sno
          INNER JOIN MeterReadingTypes MRT ON MRT.sno = MRD.ReadingTypeId
  WHERE   MRT.sno IN (7,10,11)
  GROUP BY
          MRT.sno,MRT.TypeName,MR.Adate
)
SELECT  q1.*, q2.Value
FROM    q q1
        LEFT OUTER JOIN q q2 ON q2.sno = q1.sno AND q2.rn = q1.rn + 1

编辑

使用其中任何一种解决方案与您的主要区别在于,您的解决方案必须为每条记录检索先前的结果,这是一项昂贵的操作,而此解决方案本质上可以连接两个完整(相同)的数据集。

于 2013-01-04T08:05:35.130 回答