SQL Server 2008 R2: Delete duplicate rows from tables containing in view

前端 未结 4 516
孤街浪徒
孤街浪徒 2021-01-17 02:45

--Creating Table dup1

CREATE TABLE dup1
(
    cola VARCHAR(10),
    colb VARCHAR(10)
);

--Insertion of records

INSERT INTO          


        
相关标签:
4条回答
  • 2021-01-17 02:53

    Are dup1 and dup2 partitionable table? I mean if you can add a column to them that allows to understand wich table to update. e.g. date so that if you insert a date in an interval you update dup1 else dup2. If you don't have a partitioning column you could create one simply adding a column able to identify the table (e.g. a varchar(1) with value '1' or an int having value 1 for dup1 and 2 for dup2) . This column should be a part of the primary key (here I created an ID). The table could look like this:

    CREATE TABLE dbo.dup1
        (
        cola   VARCHAR (10),
        colb   VARCHAR (10),
        ID     INT IDENTITY NOT NULL,
        partit NCHAR (10) CONSTRAINT DF_dup1_partit DEFAULT ('1') NOT NULL CONSTRAINT CK_dup1 CHECK ([PARTIT]='1'),
        CONSTRAINT PK_dup1 PRIMARY KEY (ID, partit)
        )
    
    CREATE TABLE dbo.dup2
        (
        cola   VARCHAR (10),
        colb   VARCHAR (10),
        ID     INT IDENTITY NOT NULL,
        partit NCHAR (10) CONSTRAINT DF_dup2_partit DEFAULT ('2') NOT NULL CONSTRAINT CK_dup2 CHECK ([PARTIT]='2'),
        CONSTRAINT PK_dup2 PRIMARY KEY (ID, partit)
        )
    

    So that the view will be:

    CREATE VIEW V_Dup as
    SELECT * FROM dup1 UNION ALL 
    SELECT * FROM dup2
    WITH CHECK OPTION
    

    this way you will be able to use the code I posted before

    0 讨论(0)
  • 2021-01-17 03:10

    create temp. table :

    DECLARE @tempDuplicateTable AS TABLE(
        cola VARCHAR(10),
        colb VARCHAR(10)
    )
    

    insert row duplicate :

    INSERT INTO @tempDuplicateTable
        ( cola, colb )
        (
            SELECT a.cola, a.colb FROM dup1 a
            INNER JOIN dup2 b ON b.cola = a.cola AND b.colb = a.colb
        )
    

    delete duplicate data from both table dup1 and dup2 :

    DELETE a FROM dup1 a INNER JOIN @tempDuplicateTable b ON b.cola = a.cola AND b.colb = a.colb
    DELETE a FROM dup2 a INNER JOIN @tempDuplicateTable b ON b.cola = a.cola AND b.colb = a.colb
    

    if you just want this result :

     cola   colb
       1    2
       1    3
       1    4
       1    5
       2    3
       2    4
    

    try this query :

    SELECT DISTINCT * FROM V_Dup 
    

    or you can modify your View like this :

    CREATE VIEW V_Dup as
        SELECT DISTINCT a.* FROM (
        SELECT * FROM dup1 UNION ALL 
        SELECT * FROM dup2
    ) a
    
    0 讨论(0)
  • 2021-01-17 03:13

    I guess you want just to see record once in your view because you say you want to keep original data. So you should use UNION instead of UNION ALL in your view

    CREATE VIEW V_Dup as
    SELECT * FROM dup1 UNION  
    SELECT * FROM dup2;
    

    Otherwise if you want to delete all the duplicated rows from table generating view you will have to do something like this:

    ;WITH DUP_CTE AS
    (
    SELECT  cola, colb,ROW_NUMBER() OVER (PARTITION BY cola,colb ORDER BY (SELECT 0)) RN FROM V_Dup 
    )
    DELETE FROM DUP_CTE
    
    WHERE EXISTS( SELECT 0 FROM dup_cte AS c WHERE c.cola=dup_cte.cola AND c.colb=dup_cte.colb AND RN <> 1);
    

    If you want to delete only duplicates:

    ;WITH DUP_CTE AS
        (
        SELECT  cola, colb,ROW_NUMBER() OVER (PARTITION BY cola,colb ORDER BY (SELECT 0)) RN FROM V_Dup 
        )
        DELETE FROM DUP_CTE
        WHERE  RN <> 1;
    

    But you will need a primary key in your tables for the last two solutionz.

    0 讨论(0)
  • 2021-01-17 03:19

    Create a temp table with the rows need to be deleted from CTE and delete those from both the tables.

    Query

    CREATE TABLE dup1
    (
        cola VARCHAR(10),
        colb VARCHAR(10)
    );
    
    INSERT INTO dup1 VALUES('1','2');
    INSERT INTO dup1 VALUES('1','2');
    INSERT INTO dup1 VALUES('1','3');
    INSERT INTO dup1 VALUES('1','4');
    INSERT INTO dup1 VALUES('1','5');
    
    CREATE TABLE dup2
    (
        cola VARCHAR(10),
        colb VARCHAR(10)
    );
    
    INSERT INTO dup2 VALUES('1','2');
    INSERT INTO dup2 VALUES('1','2');
    INSERT INTO dup2 VALUES('2','3');
    INSERT INTO dup2 VALUES('2','4');
    INSERT INTO dup2 VALUES('1','5');
    
    CREATE VIEW V_Dup as
    SELECT * FROM dup1 UNION ALL
    SELECT * FROM dup2;
    
    ;with cte as 
    (
        select rn=row_number() over
        (
            partition by cola,colb
            order by cola,colb
        ),*
        from V_Dup
    )
    select * into #temp
    from cte 
    where rn>1;
    
    delete t1 from dup1 t1
    inner join  #temp t2
    on t1.cola = t2.cola
    and t1.colb = t2.colb;
    
    delete t1 from dup2 t1
    inner join  #temp t2
    on t1.cola = t2.cola
    and t1.colb = t2.colb;
    
    drop table #temp;
    
    0 讨论(0)
提交回复
热议问题