【问题标题】:Why query within query results in duplicate records为什么在查询中查询会导致重复记录
【发布时间】:2017-02-23 08:41:47
【问题描述】:

我无法理解。

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

【问题讨论】:

  • 这是一个愚蠢的问题 - 您是否有可能在配置文件表中有重复的 ID?
  • @paqash 不可能。 ID 是主键。
  • 尝试运行SELECT id FROM profiles... except SELECT distinct id FROM profiles.. 以获取“不明确的 id”列表?..

标签: postgresql subquery in-subquery


【解决方案1】:

有两种可能:

  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;
    

    这将返回重复的ids。

    您是否在该列上缺少UNIQUEPRIMARY KEY 约束?

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

    如果将enable_indexscanenable_bitmapscanenable_indexonlyscan 设置为off 可以解决问题,则说明您的索引已损坏。 REINDEX TABLE profiles 可能会解决这个问题。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多