Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deleting 'equivalent' data from two tables

I need to perform the following pseudo logic in a SQL Server 2012 procedure, based around a table variable and a table declared as such:

DECLARE @tmp TABLE
    (
    ID int IDENTITY(1,1),
    UserID int NOT NULL,
    SgsID int NOT NULL
    )

CREATE TABLE #Table1
    (
    ID int IDENTITY(1,1),
    UserID int NOT NULL,
    SgsID int NOT NULL
    )
  1. For each row of data in table variable @tmp
  2. Delete rows from Table1 where UserID/SgsID combinations match UserID/SgsID in Table1
  3. Delete those UserID/SgsID combinations from @tmp that have been deleted from Table1

I've been researching different approaches, such as using OUTPUT INTO and INTERSECT, but cannot write a query that deletes across two tables (in fact I don't think it is even possible).

I have achieved the above steps by using the following code, however, I was wondering if any T-SQL pro's may be able to suggest a more succinct/efficient approach?

See SQLFiddle for online version

CREATE TABLE #Table1
    (
    ID int IDENTITY(1,1),
    UserID int NOT NULL,
    SgsID int NOT NULL
    )

INSERT INTO #Table1 (UserID, SgsID) VALUES (5, 99)
INSERT INTO #Table1 (UserID, SgsID) VALUES (10, 89)
INSERT INTO #Table1 (UserID, SgsID) VALUES (150, 79)
INSERT INTO #Table1 (UserID, SgsID) VALUES (200, 69)
INSERT INTO #Table1 (UserID, SgsID) VALUES (250, 59)
SELECT * FROM #Table1 

DECLARE @tmp TABLE
    (
    ID int IDENTITY(1,1),
    UserID int NOT NULL,
    SgsID int NOT NULL
    )

INSERT INTO @tmp (UserID, SgsID) VALUES (150, 79)
INSERT INTO @tmp (UserID, SgsID) VALUES (200, 69)
INSERT INTO @tmp (UserID, SgsID) VALUES (250, 59)
INSERT INTO @tmp (UserID, SgsID) VALUES (999, 49)
SELECT * FROM @tmp

DECLARE @tbl_commonRows TABLE (UserID int, SgsID int)
INSERT INTO @tbl_commonRows 
    (
    UserID,
    SgsID
    ) 
SELECT 
    UserID,
    SgsID 
FROM
    #Table1
INTERSECT 
SELECT
    UserID,
    SgsID
FROM
    @tmp 

DELETE FROM 
    #Table1 
WHERE 
    (ID IN (
        SELECT 
            ID 
        FROM 
            #Table1 t1 INNER JOIN
            @tbl_commonRows c ON c.UserID = t1.UserID AND c.SgsID = t1.SgsID))

DELETE FROM
    @tmp
WHERE
    (ID IN (
        SELECT
            ID
        FROM
            @tmp t2 INNER JOIN
            @tbl_commonrows c ON c.UserID = t2.UserID AND c.SgsID = t2.SgsID))

SELECT * FROM #Table1 
SELECT * FROM @tmp
DROP TABLE #Table1
like image 810
EvilDr Avatar asked Mar 06 '13 11:03

EvilDr


3 Answers

Here's solution:

DECLARE @tmp_ids TABLE (
    id1 INT,
    id2 INT
)

INSERT INTO @tmp_ids (id1, id2)
SELECT 
    t1.id,
    t2.id
FROM Table1 t1
INNER JOIN tmp t2
    on (t1.UserID = t2.UserID AND t1.SgsID = t2.SgsID)

DELETE FROM Table1
WHERE id IN (SELECT id1 FROM @tmp_ids)

DELETE FROM tmp
WHERE id IN (SELECT id2 FROM @tmp_ids)

Keep in mind - i created physical tables tmp and Table1

like image 78
Sergio Avatar answered Oct 19 '22 13:10

Sergio


You can take advantage of the fact that the OUTPUT command can take more than INSERTED and DELETED columns for deletes (but not inserts, sadly):

    DECLARE @output TABLE (id int) 

    DELETE FROM tbl
    OUTPUT tmp.ID INTO @output(id)
    FROM #Table1 tbl
    JOIN @tmp tmp 
        ON tbl.UserID = tmp.UserID 
        AND tbl.SgsID = tmp.SgsID

    DELETE FROM tmp
    FROM @tmp tmp
    JOIN @Output outp ON tmp.id = outp.id   
like image 22
Jason Whitish Avatar answered Oct 19 '22 14:10

Jason Whitish


Have you looked into using MERGE for this? Might be another option, and the syntax is nice and easy to follow.

MERGE (Transact-SQL)

like image 33
steoleary Avatar answered Oct 19 '22 13:10

steoleary