SQL 查询有效地选择不完美的重复项

Posted

技术标签:

【中文标题】SQL 查询有效地选择不完美的重复项【英文标题】:SQL query to efficiently select non-perfect duplicates 【发布时间】:2018-05-09 18:05:35 【问题描述】:

我有一个实体-属性-值格式的数据库表,如下所示:

我希望选择“实体”和“属性”列具有相同值但“值”列具有不同值的所有行。所有三列具有相同值的多行应被视为单行。我实现这一点的方法是使用 SELECT DISTINCT。

SELECT entity_id, attribute_name, COUNT(attribute_name) AS NumOcc 
FROM (SELECT DISTINCT * FROM radiology) x 
GROUP BY entity_id,attribute_name 
HAVING COUNT(attribute_name) > 1

Response for this query

但是,我了解到使用 SELECT DISTINCT 的成本很高。我计划在非常大的表上使用此查询,我正在寻找一种优化此查询的方法,可能不使用 SELECT DISTINCT。

我使用的是 PostgreSQL 10.3

【问题讨论】:

【参考方案1】:
select  *
from    radiology r
join    (
        select  entity_id
        ,       attribute_name
        from    radiology
        group by
                entity_id
        ,       attribute_name
        having  count(distinct value) > 1
        ) dupe
 on     r.entity_id = dupe.entity_id
        and r.attribute_name = dupe.attribute_name

【讨论】:

【参考方案2】:

这应该适合你:

select a.* from radiology a join 
(select entity, attribute, count(distinct value) cnt
from radiology 
group by entity, attribute
having count(distinct value)>1)b
on a.entity=b.entity and a.attribute=b.attribute

【讨论】:

这与戈登的回答是一样的。也许我没有很好地表达我的问题:^)。我希望将两个“完美重复”行解析为一行。【参考方案3】:

我希望选择“实体”和“属性”列具有相同值但“值”列具有不同值的所有行。

您的方法不这样做。我想exists:

select r.*
from radiology r
where exists (select 1
              from radiology r2
              where r2.entity = r.entity and r2.attribute = r.attribute and
                    r2.value <> r.value
             );

如果您只想要带有对的实体/属性值,请使用group by

select entity, attribute
from radiology
group by entity, attribute
having min(value) <> max(value);

请注意,您可以使用having count(distinct value) &gt; 1,但count(distinct)min()max() 产生更多开销。

【讨论】:

第一次查询不应该是r2.value &lt;&gt; r.value吗? @Andomar 。 . .谢谢。 此解决方案提取“完美重复”行(示例图像中的第 10 行和第 11 行),而不仅仅是一个。目的是将两个重复的行解析为一行。 @NoahRoseLedesma 。 . .第二个查询应该这样做。

以上是关于SQL 查询有效地选择不完美的重复项的主要内容,如果未能解决你的问题,请参考以下文章

MySQL查询有效地返回不包括重复信息的组合行

SQL查询,如何去除重复的记录?

如何在查询生成器中有效地转换嵌套 SQL [重复]

SQL合并两个具有不同列号的选择查询,同时删除重复项?

sql 查询 - 在 12 小时内选择重复项

选择查询以显示具有最大日期的重复项