为什么在查询结果中查询重复记录

时间:2017-02-23 08:41:48

标签: postgresql subquery in-subquery

我无法理解这一点。

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查询不会让任何重复的配置文件计数。我对吗?或者我有什么遗失的东西?

更新

我尝试将查询减少到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 个答案:

答案 0 :(得分:0)

有两种可能性:

  1. Chart.controllers["area"]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;

    您是否错过了该列的idUNIQUE约束?

  2. 如果PRIMARY KEY上存在UNIQUEPRIMARY KEY约束,则表示您正面临数据损坏。查看查询计划 - 它是使用索引扫描还是顺序扫描?

    如果设置idenable_indexscanenable_bitmapscanenable_indexonlyscan可以解决问题,那么您的索引就会损坏。 off可能会解决问题。

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

    在任何情况下,如果是数据损坏,请查找其原因并进行修复。它可能是有缺陷的RAM或存储,或者存储器上的服务器崩溃,不能正确地遵循同步请求。阅读数据库日志!