2010-05-27 55 views
-1

我有許多設備的檢查記錄集。四個感興趣的欄目是equip_id, month, year, myData使用前一期間的值添加缺失行的查詢

我的要求是每個設備每月都有一個正確的記錄。

我有一個查詢,通過equip_id, month, year使數據唯一。因此,一件設備每個月/每年的記錄不會超過一個。但現在我需要模擬失蹤月份的數據。我想簡單回顧一下以獲取我的最後一部分數據。

所以這可能看起來很混亂,所以我會以身作則。

鑑於這種樣本數據:

equip_id month year myData 
----------------------------- 
1   1  2010 500 
1   2  2010 600 
1   5  2010 800 
2   2  2010 300 
2   4  2010 400 
2   6  2010 500 

我想這樣的輸出:

equip_id month year myData 
----------------------------- 
1   1  2010 500 
1   2  2010 600 
1   3  2010 600 
1   4  2010 600 
1   5  2010 800 
2   2  2010 300 
2   3  2010 300 
2   4  2010 400 
2   5  2010 400 
2   6  2010 500 

請注意,我是從這個月(兩個月等)填寫丟失的數據與數據之前。另外請注意,如果裝備2的第一個記錄是在2010年2月比我不需要1/2010的記錄,即使我有一個裝備1.

我只需要正好一個記錄每個月/每件設備一年。因此,如果記錄不存在,我只想回到過去並獲取該記錄的數據。

謝謝!

+3

我可以建議你使用一個更具描述性問題的名字嗎? – tomfanning 2010-05-28 11:55:02

回答

3

並不完美:

SELECT equip_id, month, mydata 
FROM (

    SELECT equip_id, month, mydata FROM equip 
    UNION ALL 
    SELECT EquipNum.equip_id, EquipNum.Num, 
    (SELECT Top 1 mydata 
     FROM equip 
     WHERE equip.month<n.num And equip.equip_id=equipnum.equip_id 
     ORDER BY equip.month desc) AS Data 
    FROM 
    (SELECT e.equip_id, n.Num 
     FROM 
     (SELECT DISTINCT equip_id FROM equip) AS e, 
    Numbers AS n) AS EquipNum 
    LEFT JOIN equip 
    ON (EquipNum.Num = equip.month) 
    AND (EquipNum.equip_id = equip.equip_id) 
    WHERE EquipNum.Num<DMax("month","equip") 
    AND 
    (SELECT top 1 mydata 
     FROM equip 
     WHERE equip.month<n.num And equip.equip_id=equipnum.equip_id 
     ORDER BY equip.month desc) Is Not Null 
    AND equip.equip_id Is Null AND equip.Month Is Null) AS x 
ORDER BY equip_id, month 

對於這個工作,你需要一個數字表,在這種情況下,它只需1持有整數12.我用數字表是被叫號碼和領域被稱爲Num。

重新編輯評論幾年

SELECT equip_id, year, month, mydata 
FROM (

    SELECT equip_id, year, month, mydata FROM equip 
    UNION ALL 
    SELECT en.equip_id, en.year, en.Num, (SELECT Top 1 mydata 
     FROM equip e 
     WHERE e.month<n.num And e.year=en.year And e.equip_id=en.equip_id 
     ORDER BY e.month desc) AS Data 
    FROM (SELECT e.equip_id, n.Num, y.year 
     FROM 
    (SELECT DISTINCT equip_id FROM equip) AS e, 
    Numbers AS n, 
    (SELECT DISTINCT year FROM equip) AS y) AS en 
    LEFT JOIN equip AS e ON en.equip_id = e.equip_id 
    AND en.year = e.year 
    AND en.Num = e.month 
    WHERE en.Num<DMax("month","equip") AND 
    (SELECT Top 1 mydata 
     FROM equip e 
     WHERE e.month<n.num And e.year=en.year And e.equip_id=en.equip_id 
     ORDER BY e.month desc) Is Not Null 
    AND e.equip_id Is Null 
    AND e.Month Is Null) AS x 

ORDER BY equip_id, year, month 
+0

哇!感謝您的回答!然而...年並不包括在該查詢的任何地方,我有數據回到2007年...我錯過了什麼? – kralco626 2010-05-28 11:19:35

+0

沒有。我只是忽略了一年:) – Fionnuala 2010-05-28 11:36:02

+0

我注意到我在整理中也犯了一個錯誤,現在我已經糾正了。我會看看年。 – Fionnuala 2010-05-28 11:49:31

0

我已經調整爲考慮年份和月份......主要原則與原始查詢僅在當月提供的內容保持不變。但是,要申請一個月和一年,您需要測試年份+月份的設置,即:如果2009年11月份,然後跳轉到2010年2月份,會發生什麼情況,您不能只依賴一個月少於另一月份,但是「設定」。因此,我已經應用年* 12 +月來防止假如Nov = 11 + year = 2009 = 2009 + 11 = 2020,然後Feb = 2 of year = 2010 = 2010 + 2 = 2012 ...但2009 * 12 = 24108 + 11月= 11 = 24119與2010年相比* 12 = 24120 + 2月= 2 = 24122 - 保留每年/每月組合的正確順序。其他原則適用。然而,另外一個,我創建了一個表來表示要考慮的年限。對於我的測試,我在2009年11月添加了一個樣本Equip_ID = 1條目,並在2011年2月添加了Equip_ID = 2條目以及正確的翻轉工作。 (表C_Years,列=年和2009年,2010年,2011值)

SELECT 
     PYML.Equip_ID, 
     PYML.Year, 
     PYML.Mth, 
     P1.MyData 
    FROM 
     (SELECT 
      PAll.Equip_ID, 
      PAll.Year, 
      PAll.Mth, 
      (SELECT MAX(P1.Year*12+P1.Mth) 
        FROM C_Preset P1 
        WHERE PAll.Equip_ID = P1.Equip_ID 
        AND P1.Year*12+P1.Mth <= PAll.CurYrMth) as MaxYrMth 
      FROM 
       (SELECT 
         PYM1.Equip_ID, 
         Y1.Year, 
         M1.Mth, 
         Y1.Year*12+M1.Mth as CurYrMth 
        FROM 
         (SELECT p.equip_id, 
           MIN(p.year*12+p.mth) as MinYrMth, 
           MAX(p.year*12+p.mth) as MaxYrMth 
          FROM 
           C_Preset p 
          group by 
           1 
        ) PYM1, 
         C_Years Y1, 
         C_Months M1 
        WHERE 
          Y1.Year*12+M1.Mth >= PYM1.MinYrMth 
         AND Y1.Year*12+M1.Mth <= PYM1.MaxYrMth 
      ) PAll 
    ) PYML, 
     C_Preset P1 
    WHERE 
      PYML.Equip_ID = P1.Equip_ID 
     AND PYML.MaxYrMth = P1.Year*12+P1.Mth 

如果這將是一個但卻難免重複的事情/報告,我只是想創建一個臨時表在12個月 - 然後使用作爲主表,並對其餘數據執行左外部連接。這樣,你就知道你每個月都會得到,但是隻有當確認了「對方」的有效連接時,你纔會得到這些數據。 Ooops ...錯過了關於從最後一個元素中填充缺失元素的觀點......思考......

以下工作...我將描述發生了什麼的元素。首先,我創建了一個臨時表「C_Months」,其中列第M(月)的數字爲1-12。我使用「Mth」作爲Month的縮寫,以避免與POSSIBLE保留字MONTH發生衝突。此外,在我的查詢中,表引用「C_Preset」是您提到的已準備好的獨特元素的數據集。

SELECT 
     LVM.Equip_ID, 
     LVM.Mth, 
     P1.Year, 
     P1.MyData 
    FROM 
     (SELECT 
       JEM.Equip_ID, 
       JEM.Mth, 
       (SELECT MAX(P.Mth) 
        FROM C_Preset P 
        WHERE P.Equip_ID = JEM.Equip_ID 
        AND P.Mth <= JEM.Mth) as MaxMth 
      FROM 
       (SELECT distinct 
         p.equip_id, 
         c.mth 
        FROM 
         C_months c, 
         C_Preset p 
        group by 
         1, 2 
        HAVING 
          c.mth >= MIN(p.Mth) 
         and c.mth <= MAX(p.Mth) 
        ORDER BY 
         1, 2) JEM 
    ) LVM, 
     C_Preset P1 
    WHERE 
      LVM.Equip_ID = P1.Equip_ID 
     AND LVM.MaxMth = P1.Mth 
    ORDER BY 
     1, 2 

最內層查詢是查詢與給定設備ID關聯的可用月份(C_Months)。在您的示例中,設備ID 1的值爲1,2,5。所以這會返回1,2,3,4,5。對於設備ID 2,它以2開始,但以6結束,所以它將返回2,3,4,5,6。因此,別名參考JEM(Just Equipment Months)

然後, MaxMth(最多一個月)......這是棘手的

 (SELECT MAX(P.Mth) 
      FROM C_Preset P 
      WHERE P.Equip_ID = JEM.Equip_ID 
      AND P.Mth <= JEM.Mth) as MaxMth 

由此看來,說我想用給定的設備是已達到或超過一個月在問題LESS(相關聯的最大可用一個月(從JEM)檢測合格名單中最高的「有效」設備項目/月份,結果導致...

Equip_ID Mth MaxMth 
    1  1  1 
    1  2  2 
    1  3  2 
    1  4  2 
    1  5  5 

    2  2  2 
    2  3  2 
    2  4  4 
    2  5  4 
    2  6  6 

因此,對於你的ID = 1的例子,你有1,2,5個月(3和4失蹤),所以3和4所指的最後一個有效月份是序列2的月份。同樣,對於ID = 2,你有2個,4個和6 ...在這裏,3會重提2,5將重提4

其餘部分是比較容易的部分。現在,我們將您的LVM(上一個有效月)結果與上面顯示的結果一起添加到您的原始C_Preset(更少記錄)中。但是由於我們現在有最後一個有效月份直接關聯到C_Preset中的現有記錄,因此我們加入了設備ID和MaxMth柱,而不是實際月。

希望這有助於...再次,你可能不得不改變我的「第m個」一欄提及「月」,以配合您的格式。

+0

這是不正常的方式,在db的意思上,設計這樣一個表。 – Fionnuala 2010-05-27 13:38:30

+0

作爲一個類似這樣的臨時表,而不是試圖強制工會12次(或更多,如果給予完整長度的月/年組合)更容易加入這樣的通用。 – DRapp 2010-05-27 13:54:58

+0

你不應該需要12次或更多的聯合。 – Fionnuala 2010-05-27 15:11:10