2013-01-04 157 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 –