2017-02-23 51 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或存储的缺陷,或者存储上的服务器崩溃,无法正确执行同步请求。阅读数据库日志!