2011-06-30 20 views
1

我目前正在研究一個問題,我有一個不雅的解決方案。我將一個記錄的多個版本存儲在一個表中。一個很好的例子就是文檔的版本。我有一個文件的多個條目。我有一個名爲Code的專欄,其中存儲了對文檔唯一的ID。每行還有一個Active字段(布爾值),表示記錄是「活動」(最新版本)還是「非活動」。在這種情況下,只有最新版本可以被激活。我這樣做是爲了方便查詢數據(而不是每個文檔的頂部)。更新SQL(SQLite)中的值的最新版本

我的數據可能是這樣的:

Code  Active VersionNo 
ABYY  0   1 
RRUP  0   1 
RRUP  0   2 
ABYY  0   2 
ABYY  0   3 
ABYY  1   4 
RRUP  1   3 

我的問題是,當我刪除記錄,我要確保該文件有一個記錄(最新一期)標記爲活動。這裏有三種情況:

  1. 我刪檔ABYY第4版 - 我想使該文件的版本3活動。
  2. 我刪除了文檔ABYY的版本3 - 我想確保版本4仍然標記爲活動。
  3. (棘手的)我刪除了文檔ABYY的第3版。後來我決定刪除版本4. - 我想要版本2被標記爲活動,這意味着你不能只從版本號中減去1。

而是基於關閉特定數據的創建複雜的查詢,我寧願創建設置活躍的領域爲0,除了具有最高版本號,它會設置爲1的所有文件的通用查詢代替。這樣,如果我不確定特定文檔的數據,我可以重複使用相同的查詢作爲「清理」腳本。

現在我被困在兩個查詢上,第二個有點長。這裏是我做的:

UPDATE documents 
SET Active = 0 
WHERE Code = 'ABYY'; 

UPDATE documents u 
SET Active = 1 
WHERE id = (SELECT TOP 1 id 
      FROM documents 
      WHERE Code = 'ABYY' 
      ORDER BY VersionNo DESC); 

我可能可以將這些查詢合併爲一個查詢(最好也是簡單的)?我正在寫這個SQLite(最新版本)。

+0

我認爲這不是一個好設計。你可能會認爲你通過存儲一個活躍的標誌來簡化你的生活,但是現在的問題表明,沒有免費的午餐,並且不用使用最新版本的日期來獲取最新版本的文檔,在其他地方支付。我會擺脫標誌並實施基於版本日期的規則。如果您想忽略它,您可以將版本標記爲「已刪除」。 – Tim

回答

1

嘗試:

UPDATE DOCUMENTS 
    SET active = CASE 
        WHEN id = (SELECT d.id 
           FROM DOCUMENTS d 
           WHERE d.code = DOCUMENTS.code 
          ORDER BY d.versionno DESC 
           LIMIT 1) THEN 1 
        ELSE 0 
       END 
WHERE code = 'ABYY' 
0

你不能摺疊查詢,至少不是他們編寫的方式,因爲在第一個UPDATE查詢中,你將設置「Active = 0」而另一個設置爲「Active = 1」 。

如果您想保存更新所有這些「活動」字段爲0,你可以這樣做:

UPDATE documents 
SET Active = 0 
WHERE Code = 'ABYY' && Active = 1; 

這應該使它所以目前僅與該代碼的活動記錄被更改,而不是所有記錄該代碼(甚至那些已經是Active = 0的代碼)。

+0

我試圖做的是確保每一個其他項目被標記爲零。如果它是在一個查詢中完成的,你可以說「其他任何項目」,但如果你是在兩個這樣做,你真的不能。這就是爲什麼我把一切都標記爲零,然後在第二個查詢中我標記了正確的一對一。 – IAmTimCorey

0

這應做到:

UPDATE TheTable 
SET Active=(VersionNo=(SELECT MAX(VersionNo) 
         FROM TheTable AS T1 
         WHERE T1.code=TheTable.code)) 
WHERE code='RRUP' 

此外,正常化整個表,只是刪除從外更新where子句:

UPDATE TheTable 
SET Active=(VersionNo=(SELECT MAX(VersionNo) 
         FROM TheTable AS T1 
         WHERE T1.code=TheTable.code))