改进SQL查询以查找冗余数据

时间:2018-10-25 08:00:14

标签: sql sql-server tsql sql-server-2008 duplicates

下面显示了我的样本数据集

Line

这是我从last request获得的查询:

LineSegment

现在,我要调整查询以仅输出以下数据:

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

姓氏可以用','或'^'分隔。如果相同的PatientID的姓氏相同,那么我不希望它们被显示。我尝试摆弄一个带有CHARINDEX命令和其他命令的子选择语句,但是由于请求的复杂性,我的SQL语法知识非常有限。

请注意,对于XXX-3188,该案例包含两个姓氏相同的数据集,但另一个具有完整的PatientName的数据集,因此需要将其包含在输出中。

2 个答案:

答案 0 :(得分:1)

尝试一下:

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

解决方案非常简单。这里是有趣的部分:

  • ^替换为,,以简化姓氏提取操作
  • 根据IDlast name提取姓氏和计算次数
  • 在最终选择中检查id-last name等于id的唯一2对,并添加ID并添加一个以上唯一的家族名称(您的特殊情况)

答案 1 :(得分:0)

您可以尝试类似的操作:

测试数据

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;