2012-09-07 58 views
1

我發現了兩個錯誤在創造了很多重複值的程序更新PostgreSQL表:如何與重複的項目數

  • 一個「指數」的創建,而不是「唯一索引」
  • 一個重複檢查,並沒有集成在4的一個扭曲的程序

所以我需要去收拾我的數據庫。

第一步是裝飾表與所有的重複值的計數(接下來我馬上去找到的第一個值,然後再進行遷移的一切)

以下作品的代碼,我回想起剛纔在做幾年前在同一張表上也有類似的「select count」更新,而且我只用了一半的代碼。

有沒有更好的方法來寫這個?

UPDATE 
    shared_link 
SET 
    is_duplicate_of_count = subquery.is_duplicate_of_count 
FROM 
    (
     SELECT 
      count(url) AS is_duplicate_of_count 
      , url 
     FROM 
      shared_link 
     WHERE 
      shared_link.url = url 
     GROUP BY 
      url 
    ) AS subquery 
WHERE 
    shared_link.url = subquery.url 
; 

回答

3

您查詢是很好,一般,除了在子查詢的無意義的(但也無害)WHERE子句:

UPDATE shared_link 
SET is_duplicate_of_count = subquery.is_duplicate_of_count 
FROM (
    SELECT url 
     , count(url) AS is_duplicate_of_count 
    FROM shared_link 

             
  
    -- WHERE shared_link.url = url 
   
    GROUP BY url 
    ) AS subquery 
WHERE shared_link.url = subquery.url;

註釋的條款是一樣的

WHERE shared_link.url = shared_link.url 

因此只消除NULL的值(因爲NULL = NULL不是TRUE),這很可能既不是您的意圖也不是需要的etup。


除此之外,你只能用別名和較短的名稱進一步縮短代碼:

UPDATE shared_link s 
SET ct = u.ct 
FROM (
    SELECT url, count(url) AS ct 
    FROM shared_link 
    GROUP BY 1 
    ) AS u 
WHERE s.url = u.url; 

在PostgreSQL 9.1或更高版本,你可能能夠做整個操作(識別受騙者,合併數據,刪除愚蠢)在之一具有聚合和窗口函數的SQL語句和data-modifying CTEs - 因此不需要額外的列開始。

+0

非常感謝Erwin!我仍然在這臺機器上的8.4.x分支上。 –