How to update the fields having same Names and DOB?

  • Create Table #Temp (ID int not null primary Key, Name varchar(25) not null, DOB datetime not null, Sex char(1), Race char(1), Height int, Weight int)

    insert #Temp

    select 1, 'Kenneth', '1963-02-26 00:00:00.000', 'M','C', 516, 160

    union

    select 2, 'Kenneth', '1963-02-26 00:00:00.000', NULL,NULL, NULL, NULL

    union

    select 3, 'William', '1962-06-28 00:00:00.000', 'M','C', 600, 223

    union

    select 4, 'Ryan', '1980-07-05 00:00:00.000', 'M','W', 507, 145

    union

    select 5, 'Robert', '1988-09-14 00:00:00.000', NULL,'B', 601, NULL

    union

    select 6, 'Robert', '1988-09-14 00:00:00.000', 'M',NULL, NULL, 190

    union

    select 7, 'Keith', '1986-09-05 00:00:00.000', 'M','C', 600, NULL

    select * from #Temp

    /* Expecting Output */

    select 1 as ID, 'Kenneth' as Name, '1963-02-26 00:00:00.000' as DOB, 'M' as Sex,'C' as Race, 516 as Height, 160 as Weight

    union

    select 2, 'Kenneth', '1963-02-26 00:00:00.000', 'M','C', 516, 160

    union

    select 3, 'William', '1962-06-28 00:00:00.000', 'M','C', 600, 223

    union

    select 4, 'Ryan', '1980-07-05 00:00:00.000', 'M','W', 507, 145

    union

    select 5, 'Robert', '1988-09-14 00:00:00.000', 'M','B', 601, 190

    union

    select 6, 'Robert', '1988-09-14 00:00:00.000', 'M','B', 601, 190

    union

    select 7, 'Keith', '1986-09-05 00:00:00.000', 'M','C', 600, NULL

    HI Friends,

    I have posted the DDL and DML. It's just an sample.

    I want to update the fields that with same Name and DOB. It's like duplicate row but with primary key different.

    How to do this ?

    Any suggestions would be appreciated. Please let me know if I am not clear.

  • Window function solution, works on 2012 and later

    ๐Ÿ˜Ž

    Create Table #Temp (ID int not null primary Key, Name varchar(25) not null, DOB datetime not null, Sex char(1), Race char(1), Height int, Weight int);

    insert #Temp

    select 1, 'Kenneth', '1963-02-26 00:00:00.000', 'M','C', 516, 160 union

    select 2, 'Kenneth', '1963-02-26 00:00:00.000', NULL,NULL, NULL, NULL union

    select 3, 'William', '1962-06-28 00:00:00.000', 'M','C', 600, 223 union

    select 4, 'Ryan', '1980-07-05 00:00:00.000', 'M','W', 507, 145 union

    select 5, 'Robert', '1988-09-14 00:00:00.000', NULL,'B', 601, NULL union

    select 6, 'Robert', '1988-09-14 00:00:00.000', 'M',NULL, NULL, 190 union

    select 7, 'Keith', '1986-09-05 00:00:00.000', 'M','C', 600, NULL

    ;WITH UPD_TBL

    AS

    (

    select

    ID

    ,Name

    ,DOB

    ,FIRST_VALUE(Sex) OVER

    (

    PARTITION BY Name,DOB

    ORDER BY Sex DESC

    ROWS BETWEEN UNBOUNDED PRECEDING

    AND UNBOUNDED FOLLOWING

    ) AS Sex

    ,FIRST_VALUE(Race) OVER

    (

    PARTITION BY Name,DOB

    ORDER BY Race DESC

    ROWS BETWEEN UNBOUNDED PRECEDING

    AND UNBOUNDED FOLLOWING

    ) AS Race

    ,FIRST_VALUE(Height) OVER

    (

    PARTITION BY Name,DOB

    ORDER BY Height DESC

    ROWS BETWEEN UNBOUNDED PRECEDING

    AND UNBOUNDED FOLLOWING

    ) AS Height

    ,FIRST_VALUE(Weight) OVER

    (

    PARTITION BY Name,DOB

    ORDER BY Weight DESC

    ROWS BETWEEN UNBOUNDED PRECEDING

    AND UNBOUNDED FOLLOWING

    ) AS Weight

    from #Temp

    )

    UPDATE T

    SET

    Sex = UT.Sex

    ,Race = UT.Race

    ,Height = UT.Height

    ,Weight = UT.Weight

    FROM UPD_TBL UT

    INNER JOIN #TEMP T

    ON UT.ID = T.ID;

    SELECT * FROM #Temp;

    DROP TABLE #Temp;

    Output

    ID Name DOB Sex Race Height Weight

    --- -------- ----------------------- ---- ---- ------- -------

    1 Kenneth 1963-02-26 00:00:00.000 M C 516 160

    2 Kenneth 1963-02-26 00:00:00.000 M C 516 160

    3 William 1962-06-28 00:00:00.000 M C 600 223

    4 Ryan 1980-07-05 00:00:00.000 M W 507 145

    5 Robert 1988-09-14 00:00:00.000 M B 601 190

    6 Robert 1988-09-14 00:00:00.000 M B 601 190

    7 Keith 1986-09-05 00:00:00.000 M C 600 NULL

  • Though following code would work but I feel there must be a easy way around.. SSC experts might help us here

    ;with cte as

    (

    SELECT DISTINCT T1.NAME,T1.DOB,

    CASE

    WHEN T1.SEX IS NULL THEN T2.Sex

    ELSE T1.Sex

    END AS SEX,

    CASE

    WHEN T1.Race IS NULL THEN T2.Race

    ELSE T1.Race

    END AS RACE,

    CASE

    WHEN T1.Height IS NULL THEN T2.Height

    ELSE T1.Height

    END AS Height,

    CASE

    WHEN T1.Weight IS NULL THEN T2.Weight

    ELSE T1.Weight

    END AS Weight

    FROM #Temp T1

    FULL OUTER JOIN #Temp T2

    ON T1.DOB = T2.DOB AND T1.Name = T2.Name

    ),

    CTE1 AS

    (

    SELECT * FROM cte WHERE SEX IS NOT NULL AND RACE IS NOT NULL AND Height IS NOT NULL AND Weight IS NOT NULL

    )

    UPDATE T1

    SET Sex = C.SEX,Race=C.RACE,Height=C.HEIGHT,Weight=C.WEIGHT

    FROM #Temp T1

    INNER JOIN CTE1 C

    ON T1.Name = C.Name AND T1.DOB = C.DOB

  • Old-fashioned solution, works on every version of SQL Server:

    -- Check using SELECT

    SELECT *

    FROM #Temp t1

    INNER JOIN (

    SELECT Name, DOB, Sex = MAX(Sex), Race = MAX(Race), Height = MAX(Height), Weight = MAX(Weight)

    FROM #Temp

    GROUP BY Name, DOB

    HAVING COUNT(*) > 1

    ) t2 ON t2.Name = t1.Name AND t2.DOB = t1.DOB

    -- Perform UPDATE

    UPDATE t1 SET Sex = t2.Sex, Race = t2.Race, Height = t2.Height, Weight = t2.Weight

    FROM #Temp t1

    INNER JOIN (

    SELECT Name, DOB, Sex = MAX(Sex), Race = MAX(Race), Height = MAX(Height), Weight = MAX(Weight)

    FROM #Temp

    GROUP BY Name, DOB

    HAVING COUNT(*) > 1

    ) t2 ON t2.Name = t1.Name AND t2.DOB = t1.DOB

    -- Check results

    SELECT * FROM #Temp

    โ€œWrite the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.โ€ - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • Hi Chris,

    The query you have given is really easy to understand....Thank you so much..

  • Hi Eirik,

    First of all thanks to you because you have taught me new functions like unbounded. and a new way of writing query.....I have never heard about that....

Viewing 6 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic. Login to reply