2015-07-08 3 views
0

Я пытаюсь найти способ пометить дублированные случаи, подобные этому question.Postgresql: маркировка и идентификация дубликатов

Однако, вместо подсчета вхождения дублированных значений, я хотел бы отметить их как 0 и 1, для дублированных и уникальных случаев соответственно. Это очень похоже на функцию 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 

бонус будет утверждение запроса который будет обрабатывать, какой случай выбрать при определении уникального случая.

+0

1) Есть ли лет Ур таблица имеет первичный ключ (например, идентификатор)? 2) ПОЧЕМУ {Джон, Техас] дуп, а {Джон, SD} нет? 3) Почему {Ариэль, Флорида} дублирует? 4) то же самое для {Noah, CA} – wildplasser

+0

В этом примере мы можем предположить, что имена являются первичными ключами. Возможно, я сформулировал это неправильно, но Ариэль и Ной не дубликаты. Это первое появление Ариэля и Ноя, поэтому оно помечено как 1. В то время как 2-й Катнисс и Джон равны нулю, потому что раньше были Катнисс и Джон (строки 1 и 2). –

+0

У вас был знак перевернутый. (поэтому я назвал столбец результатов «nodup») – wildplasser

ответ

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) 
+0

Я не сомневаюсь, что вы правы, но у меня есть немного проблем с интерпретацией этого (я все еще новичок в postgres). Существуют ли в базе данных 'nx' и' na' разные таблицы? Также откуда берется «ctid»? –

+0

Нет, это * тот же * таблица. Вы должны прочитать подзапрос как «существует ли другая запись с тем же именем, но с другим номером записи?» Этот подзапрос выводит логическое значение для каждой записи основного запроса. ctid - это «скрытые столбцы», * вид * рулона, гарантированный для каждой строки. Мне это было нужно, потому что для этого пурпуса не было столбца PK/id. – wildplasser

+0

Нет, это * скрытый * столбец, поддерживаемый СУБД в своих целях (управление версиями строк). Другие DBMS могут иметь другие используемые столбцы (tid, tidp, rownum, ...), которые могут быть использованы. BTW: вы можете избежать необходимости в ctid (и путанице), имея PRIMARY KEY (или UNIQUE ограничение) для каждой таблицы. – wildplasser

Смежные вопросы