2017-02-23 60 views
1

我無法理解這個查詢結果中查詢。爲什麼重複的記錄

SELECT COUNT(*) FROM profiles 
WHERE profiles.status IN ('abc', 'man') 
    AND profiles.id IN (
         SELECT artifacts.item_id FROM artifacts 
         WHERE artifacts.deleted_at IS NULL 
          AND artifacts.item_type = 'Profile' 
          AND artifacts.upload_type = 'bill' 
        ); 
count 
------- 
12514 
(1 row) 

上面的查詢計數配置文件的重複記錄(爲此,工件有多個記錄)。當我以不同的方式運行上述查詢時,我會得到正確的計數,如下所示。

SELECT COUNT(DISTINCT(id)) FROM profiles 
WHERE profiles.status IN ('abc', 'man') 
    AND profiles.id IN (
         SELECT artifacts.item_id FROM artifacts 
         WHERE artifacts.deleted_at IS NULL 
          AND artifacts.item_type = 'Profile' 
          AND artifacts.upload_type = 'bill' 
        ); 
count 
------- 
12157 
(1 row) 

工件可以對同一配置文件有多個記錄。但根據我的理解IN查詢不會讓任何重複的配置文件進入計數。我對嗎?還是有什麼我失蹤?

UPDATE:

我試圖查詢減少到2個不同的過濾條件。這兩個條件都很好。如下請見。

=> SELECT COUNT(*) FROM profiles WHERE profiles.id IN (
      SELECT artifacts.item_id FROM artifacts 
      WHERE artifacts.deleted_at IS NULL 
      AND artifacts.item_type = 'Profile' 
      AND artifacts.upload_type = 'bill'); 
count 
------- 
22664 
(1 row) 

=> SELECT COUNT(DISTINCT(id)) FROM profiles WHERE profiles.id IN (
      SELECT artifacts.item_id FROM artifacts 
      WHERE artifacts.deleted_at IS NULL 
      AND artifacts.item_type = 'Profile' 
      AND artifacts.upload_type = 'bill'); 
count 
------- 
22664 
(1 row) 


=> SELECT COUNT(DISTINCT(id)) FROM profiles 
     WHERE profiles.status IN ('abc', 'man'); 
count 
------- 
20109 
(1 row) 

=> SELECT COUNT(*) FROM profiles 
     WHERE profiles.status IN ('abc', 'man'); 
count 
------- 
20109 

時一起選擇使用兩種IN查詢,以便發生重複。有沒有人熟悉這種用例。

+1

這是一個愚蠢的問題 - 你有任何機會在配置文件表中有重複的id? – paqash

+0

@paqash不可能。 Id是主鍵。 – dnsh

+0

嘗試運行'SELECT ID從配置......除了選擇不重複的ID從profiles..'得到「沒有明顯的ID」的名單?.. –

回答

0

有兩種可能性:

  1. idprofiles獨特。

    您可以運行下面的查詢來研究這個:

    SELECT profiles.id, count(*) FROM profiles 
    WHERE profiles.status IN ('abc', 'man') 
        AND profiles.id IN (
             SELECT artifacts.item_id FROM artifacts 
             WHERE artifacts.deleted_at IS NULL 
              AND artifacts.item_type = 'Profile' 
              AND artifacts.upload_type = 'bill' 
            ) 
    GROUP BY profiles.id 
    HAVING count(*) > 1; 
    

    這將返回id S中的重複。

    是否缺少該列有UNIQUEPRIMARY KEY約束?

  2. 如果在id上存在UNIQUEPRIMARY KEY約束,則表明您正面臨數據損壞。查看查詢計劃–它使用索引掃描還是順序掃描?

    如果設置enable_indexscan,enable_bitmapscanenable_indexonlyscanoff解決了問題,您的索引已損壞。 REINDEX TABLE profiles可能會解決這個問題。

    如果查詢也返回如果只是順序掃描的使用效果不好,你所面對表損壞。從上次良好的備份中恢復。

    在任何情況下,如果是數據損壞,找到其原因並解決它。它可能存在RAM或存儲的缺陷,或者存儲上的服務器崩潰,無法正確執行同步請求。閱讀數據庫日誌!