Выберите дубликаты лиц с двойным членством - PullRequest
0 голосов
/ 23 октября 2019

SQL Fiddle со схемой и моей первоначальной попыткой.

CREATE TABLE person
    ([firstname] varchar(10), [surname] varchar(10), [dob] date, [personid] int);

INSERT INTO person
    ([firstname], [surname], [dob] ,[personid])
VALUES
    ('Alice', 'AA', '1/1/1990', 1),
    ('Alice', 'AA', '1/1/1990', 2),
    ('Bob'  , 'BB', '1/1/1990', 3),
    ('Carol', 'CC', '1/1/1990', 4),
    ('Alice', 'AA', '1/1/1990', 5),
    ('Kate' , 'KK', '1/1/1990', 6),
    ('Kate' , 'KK', '1/1/1990', 7)

;

CREATE TABLE person_membership
    ([personid] int, [personstatus] varchar(1), [memberid] int);

INSERT INTO person_membership
    ([personid], [personstatus], [memberid])
VALUES
    (1, 'A', 10),
    (2, 'A', 20),
    (3, 'A', 30),
    (3, 'A', 40),
    (4, 'A', 50),
    (4, 'A', 60),
    (5, 'T', 70),
    (6, 'A', 80),
    (7, 'A', 90);

CREATE TABLE membership
    ([membershipid] int, [memstatus] varchar(1));

INSERT INTO membership
    ([membershipid], [memstatus])
VALUES
    (10, 'A'),
    (20, 'A'),
    (30, 'A'),
    (40, 'A'),
    (50, 'T'),
    (60, 'A'),
    (70, 'A'),
    (80, 'A'),
    (90, 'T');

Существует три таблицы (согласно приведенной выше скрипке). Person таблица содержит дубликаты, одни и те же люди, введенные более одного раза, для целей этого упражнения мы предполагаем, что для однозначной идентификации человека достаточно комбинации имени, фамилии и DoB.

Я пытаюсьсоздать запрос, который покажет дубликаты людей (имя + фамилия + должность) с двумя или более активными записями в таблице Person (person_membership.person_status=A) И двумя или более активными участниками (membership.mestatus=A).

Используя пример из SQL Fiddle, результатом запроса должна быть просто Алиса (два идентификатора активного лица, два идентификатора активного членства). enter image description here

Я думаю, что я продвигаюсь со следующими усилиями, но это выглядит довольно громоздко, и мне нужно удалить Кэти из окончательного результата - у нее нет дублирующего членства.

SELECT q.firstname, q.surname, q.dob, p1.personid, m.membershipid 
FROM
(SELECT
  p.firstname,p.surname,p.dob, count(*) as cnt
FROM
  person p
GROUP BY
  p.firstname,p.surname,p.dob
HAVING COUNT(1) > 1) as q
INNER JOIN person p1 ON q.firstname=p1.firstname AND q.surname=p1.surname AND q.dob=p1.dob
INNER JOIN person_membership pm ON p1.personid=pm.personid
INNER JOIN membership m ON pm.memberid = m.membershipid
WHERE pm.personstatus = 'A' AND m.memstatus = 'A'

Ответы [ 2 ]

1 голос
/ 23 октября 2019

Поскольку вы используете Windows Server, функция Windows будет полезна для этого сценария. Следующее даст вам ожидаемый результат.

SELECT firstname,surname,dob,personid,memberid
from(
SELECT firstname,surname,dob,p.personid,memberid
,Rank() over(partition by p.firstname,p.surname,p.dob order by p.personid) rnasc
,Rank() over(partition by p.firstname,p.surname,p.dob order by p.personid desc) rndesc
FROM [StagingGRG].[dbo].[person] p
INNER JOIN person_membership pm ON p.personid=pm.personid
INNER JOIN membership m ON pm.memberid = m.membershipid
where personstatus='A' and memstatus='A')a
where a.rnasc+rndesc>2
1 голос
/ 23 октября 2019

Вы должны добавить предложения Group by и Having, чтобы возвращать только повторяющиеся элементы -

SELECT
  person.firstname,person.surname,person.dob
FROM
  person, person_membership, membership
WHERE
  person.personid=person_membership.personid AND person_membership.memberid = membership.membershipid
AND
  person_membership.personstatus = 'A' AND membership.memstatus = 'A'
GROUP BY
  person.firstname,person.surname,person.dob
HAVING COUNT(1) > 1
...