Улучшение SQL-запросов для поиска избыточных данных - PullRequest
0 голосов
/ 25 октября 2018

ниже показан мой пример набора данных

PatientID        PatientName
XXX-037070002    Riger, Jens^Wicki
XXX-037070002    Riger^Wicki
XXX-10052        Weier,Nicole^Peggy
XXX-10052        Weier,Nicole^Peppy
XXX-23310        Rodem^Sieglinde
XXX-23310        Sauberger, Birgit^Finja
XXX-23343        Je, Ronny^Wilma
XXX-23343        Jer, Ronny^Wilma
XXX-2349         Kel,Andy^Juka
XXX-2349         Kel^Juka
XXX-2998         Hel, Frank
XXX-2998         Hel,Frank^Fenris
XXX-3188         Mey, Marion
XXX-3188         Mey, Marion^Paula
XXX-3188         Schulz^Roma
XXX-3218         Böntgen-Simnet,Dr. Regine^Cara
XXX-3218         Simnet,Dr. Regine^Cara
XXX-3826         Mertes, Bernd Uwe^Ellie
XXX-3826         Mertes,Bernd^Ellie
XXX-3826         Mertes^Ellie

Это запрос, который я получил из моего последнего запроса :

with d as
(   
select distinct
    patid,
    patname
from dicomstudys
)
select *
from d
where d.patid in
(   
select d.patid
from d
group by d.patid
having count(*) > 1
)

Теперь я хочу настроитьзапросить, что на выход поступают только следующие данные:

PatientID        PatientName
XXX-23310        Rodem^Sieglinde
XXX-23310        Sauberger, Birgit^Finja
XXX-23343        Je, Ronny^Wilma
XXX-23343        Jer, Ronny^Wilma
XXX-3188         Mey, Marion
XXX-3188         Mey, Marion^Paula
XXX-3188         Schulz^Roma
XXX-3218         Böntgen-Simnet,Dr. Regine^Cara
XXX-3218         Simnet,Dr. Regine^Cara

Фамилии отделены ',' или '^'.Если фамилии совпадают для идентичного PatientID, я не хочу, чтобы они отображались.Я попытался поиграться с оператором sub select, в котором есть комбинация команд CHARINDEX и других, но мои знания синтаксиса SQL очень ограничены сложностью запроса.

Обратите также внимание, что для случая для XXX-3188 есть дванаборы данных с той же фамилией, но также с другим набором данных с полным новым именем пациента, поэтому он должен быть в выходных данных.

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Попробуйте:

DECLARE @DataSource TABLE
(
    [ID] VARCHAR(32)
   ,[Name] VARCHAR(256)
);

INSERT INTO @DataSource ([ID], [Name])
VALUES ('XXX-037070002', 'Riger, Jens^Wicki')
      ,('XXX-037070002', 'Riger^Wicki')
      ,('XXX-10052', 'Weier,Nicole^Peggy')
      ,('XXX-10052', 'Weier,Nicole^Peppy')
      ,('XXX-23310', 'Rodem^Sieglinde')
      ,('XXX-23310', 'Sauberger, Birgit^Finja')
      ,('XXX-23343', 'Je, Ronny^Wilma')
      ,('XXX-23343', 'Jer, Ronny^Wilma')
      ,('XXX-2349', 'Kel,Andy^Juka')
      ,('XXX-2349', 'Kel^Juka')
      ,('XXX-2998', 'Hel, Frank')
      ,('XXX-2998', 'Hel,Frank^Fenris')
      ,('XXX-3188', 'Mey, Marion')
      ,('XXX-3188', 'Mey, Marion^Paula')
      ,('XXX-3188', 'Schulz^Roma')
      ,('XXX-3218', 'Böntgen-Simnet,Dr. Regine^Cara')
      ,('XXX-3218', 'Simnet,Dr. Regine^Cara')
      ,('XXX-3826', 'Mertes, Bernd Uwe^Ellie')
      ,('XXX-3826', 'Mertes,Bernd^Ellie')
      ,('XXX-3826', 'Mertes^Ellie');

WITH DataSource AS
(
    SELECT [ID]
          ,[Name]
          ,COUNT(*) OVER (PARTITION BY [ID], LTRIM(RTRIM(SUBSTRING([Name],  0, CHARINDEX(',', REPLACE([Name], '^', ',')))))) AS [ID_Name_Count]
          ,COUNT(*) OVER (PARTITION BY [ID]) AS [ID_Count]
          ,LTRIM(RTRIM(SUBSTRING([Name],  0, CHARINDEX(',', REPLACE([Name], '^', ','))))) AS [FamilyName]
    FROM @DataSource
)
SELECT [ID]
      ,[Name]
FROM DataSource
WHERE [ID_Name_Count] = 1
    AND [ID_Count] = 2
    OR [ID] IN
    (
        SELECT [ID]
        FROM DataSource
        GROUP BY [ID]
        HAVING COUNT(DISTINCT [FamilyName]) > 1
    );

enter image description here

Решение довольно простое.Вот интересные части:

  • замените ^ на ,, чтобы упростить извлечение фамилии
  • извлекать фамилию и счет вычисления на основе IDи last name
  • в окончательной проверке выбора для уникальных id-last name пар с числом id, равным 2, и добавлением идентификаторов с более чем одним уникальным именем семьи (ваш особый случай)
0 голосов
/ 25 октября 2018

Вы можете попробовать что-то подобное:

Тестовые данные

drop table if exists #Patient;

create table #Patient (
    PatientID varchar(20),
    PatientName varchar(50)
);

insert into #Patient(PatientID,PatientName) 
    values  ('XXX-037070002'   ,'Riger, Jens^Wicki'),
            ('XXX-037070002'   ,'Riger^Wicki'),
            ('XXX-10052'       ,'Weier,Nicole^Peggy'),
            ('XXX-10052'       ,'Weier,Nicole^Peppy'),
            ('XXX-23310'       ,'Rodem^Sieglinde'),
            ('XXX-23310'       ,'Sauberger, Birgit^Finja'),
            ('XXX-23343'       ,'Je, Ronny^Wilma'),
            ('XXX-23343'       ,'Jer, Ronny^Wilma'),
            ('XXX-2349'        ,'Kel,Andy^Juka'),
            ('XXX-2349'        ,'Kel^Juka'),
            ('XXX-2998'        ,'Hel, Frank'),
            ('XXX-2998'        ,'Hel,Frank^Fenris'),
            ('XXX-3188'        ,'Mey, Marion'),
            ('XXX-3188'        ,'Mey, Marion^Paula'),
            ('XXX-3188'        ,'Schulz^Roma'),
            ('XXX-3218'        ,'Böntgen-Simnet,Dr. Regine^Cara'),
            ('XXX-3218'        ,'Simnet,Dr. Regine^Cara'),
            ('XXX-3826'        ,'Mertes, Bernd Uwe^Ellie'),
            ('XXX-3826'        ,'Mertes,Bernd^Ellie'),
            ('XXX-3826'        ,'Mertes^Ellie');

Мое решение

with q1 as (
select 
    PatientID,
    PatientName,
    case when CHARINDEX(',',REPLACE( PatientName, '^',',')) > 0 
        then LEFT(PatientName,CHARINDEX(',',REPLACE( PatientName, '^',','))-1) 
        else PatientName end as FullName 
    from #Patient
) ,
q2 as (
    select PatientID 
    from q1 
    group by PatientID having COUNT(1) > 1 and COUNT(DISTINCT FullName) > 1 )
select t.PatientID,t.PatientName
from #Patient t join q2 on t.PatientID = q2.PatientID;
...