2013-01-04 115 views
2

我有以下代码SQL获取行值之间的差异?

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 Column显示前一天的值如下(上例中为最后三行)

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

如何才能做到这一点?可能有一个类似的例子来展示我的方式。

在此先感谢...

UPDATE

其实,我写了这样的事情

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 

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

+0

更新了我的问题。 –

+0

是否正确使用MAX(MRD.Value)?通常它不涉及'MR.Adate'。 – Serg

+0

代码正常工作。 –

回答

1

如果找你使用SQL Server 2012中,你可以使用新的LAG analytical function

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 

编辑

使用之间的主要区别要么这些解决方案之一是你的解决方案必须检索以前的结果对于每个记录来说是一个昂贵的操作,而这个解决方案本质上可以加入两个完整(相同)的数据集。

+0

非常感谢。我无法理解你的代码,但它比我的更好。 –

+0

@AliRızaAdıyahşi - 你使用的是SQL Server 2012还是2005/2008? –

+0

SQL Server 2008 –