【问题标题】:Postgresql: Flagging and Identifying DuplicatesPostgresql:标记和识别重复项
【发布时间】:2015-09-26 21:01:18
【问题描述】:

我正在尝试找到一种方法来标记类似于 question 的重复案例。

但是,我不想计算重复值的出现次数,而是将它们分别标记为 01,分别用于重复和唯一的情况。这与SPSS 的识别重复案例功能非常相似。例如,如果我有这样的数据集:

Name    State    Gender
John     TX        M
Katniss  DC        F
Noah     CA        M
Katniss  CA        F
John     SD        M
Ariel    FL        F     

如果我想标记具有重复名称的那些,那么输出将是这样的:

Name    State    Gender   Dup
John     TX        M       1
Katniss  DC        F       1 
Noah     CA        M       1
Katniss  CA        F       0
John     SD        M       0
Ariel    FL        F       1

一个额外的好处是一个查询语句,它将在确定唯一案例时处理要选择的案例。

【问题讨论】:

  • 1) 您的表是否有主键(例如 id)? 2) 为什么 {John,TX} 是一个骗子,而 {John,SD} 不是? 3) 为什么 {Ariel,FL} 是重复的? 4) {Noah,CA} 相同
  • 对于这个例子,我们可以假设名字是主键。我可能措辞错误,但爱丽儿和诺亚不是重复的。这是 Ariel 和 Noah 的第一次出现,因此它被标记为 1。而第二个 Katniss 和 John 为零,因为之前有 Katniss 和 John(第 1 行和第 2 行)。
  • 你把标志倒过来了。 (这就是为什么我将结果列命名为nodup
  • 我对倒置的内容感到困惑(所以我可以修复它)。这个想法是为唯一案例获得 1,为重复案例获得 0。这有帮助吗?
  • 那很好,但是请不要将变量命名为Dup,那么。将其命名为 NoDupWanted,或任何描述其用途的名称。

标签: postgresql duplicates


【解决方案1】:
SELECT name, state, gender
    , NOT EXISTS (SELECT 1 FROM names nx
            WHERE nx.name = na.name
              AND nx.gender = na.gender
              AND nx.ctid < na.ctid) AS Is_not_a_dup
FROM names na
   ;

解释:[NOT] EXISTS(...) 产生一个布尔值(可以转换为整数)转换为布尔值需要额外的一对 (),但是:

SELECT name, state, gender
        , (NOT EXISTS (SELECT 1 FROM names nx
                WHERE nx.name = na.name
                  AND nx.gender = na.gender
                  AND nx.ctid < na.ctid))::integer AS is_not_a_dup
FROM names na
       ;

结果:

DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
INSERT 0 6
  name   | state | gender | nodup 
---------+-------+--------+-------
 John    | TX    | M      | t
 Katniss | DC    | F      | t
 Noah    | CA    | M      | t
 Katniss | CA    | F      | f
 John    | SD    | M      | f
 Ariel   | FL    | F      | t
(6 rows)

  name   | state | gender | nodup 
---------+-------+--------+-------
 John    | TX    | M      |     1
 Katniss | DC    | F      |     1
 Noah    | CA    | M      |     1
 Katniss | CA    | F      |     0
 John    | SD    | M      |     0
 Ariel   | FL    | F      |     1
(6 rows)

【讨论】:

  • 我毫不怀疑你是正确的,但我在解释这一点时遇到了一些麻烦(我还是 postgres 的新手)。 nxna 是数据库中的不同表吗?还有ctid 是从哪里来的?
  • 不,它是 same 表。您应该将子查询阅读为“是否存在另一条同名但记录号不同的记录?”该子查询为主查询的每条记录生成一个布尔值。 ctid 是一个“隐藏的列”,一个行号的种类,保证每一行都不同。我需要它,因为没有可用于该目的的 PK/id 列。
  • 不,它是一个 隐藏 列,由 DBMS 维护用于其自身目的(行版本控制)。其他 DBMS 可能具有其他可用的列(tid、tidp、rownum、...)。顺便说一句:您可以通过为每个表设置一个 PRIMARY KEY(或 UNIQUE 约束)来避免对 ctid 的需要(和混淆)。
猜你喜欢
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-22
  • 2012-09-12
  • 1970-01-01
  • 2022-01-17
  • 2013-04-22
相关资源
最近更新 更多