【问题标题】:SQL query to efficiently select non-perfect duplicatesSQL 查询有效地选择不完美的重复项
【发布时间】: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

【问题讨论】:

    标签: sql postgresql query-optimization postgresql-10


    【解决方案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 。 . .第二个查询应该这样做。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      • 1970-01-01
      • 2016-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-03
      相关资源
      最近更新 更多