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)

以上查询计算了配置文件的重复记录(工件有多个记录)。当我以 distinct 运行上述查询时,我得到了正确的计数,如下所示。

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查询不会让任何重复的配置文件计算在内。我对吗?或者有什么我想念的吗?

更新:

我试图将查询减少到 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查询结合使用时,就会发生重复。有没有人熟悉这种用例。

4

1 回答 1

0

有两种可能:

  1. id中并不是唯一的profiles

    您可以运行以下查询来调查此问题:

    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. 如果 有UNIQUEPRIMARY KEY约束id,您将面临数据损坏。查看查询计划——它使用索引扫描还是顺序扫描?

    如果设置enable_indexscan,enable_bitmapscanenable_indexonlyscan修复off问题,则您的索引已损坏。REINDEX TABLE profiles可能会解决问题。

    如果仅使用顺序扫描,查询也返回错误结果,则您将面临表损坏。从上次良好的备份恢复。

    无论如何,如果是数据损坏,请找出原因并修复它。它可能是有缺陷的 RAM 或存储,或者存储上的服务器崩溃无法正确处理同步请求。阅读数据库日志!

于 2017-02-23T09:16:39.513 回答