0

This is a question in Leetcode: https://leetcode.com/problems/delete-duplicate-emails/solution/

Basically the question asks to delete duplicate emails and keep the one that has the minumal index.

My code is the following one, and I firstly ran it in SQL Server mode, and it shows "Internal Error". But it has passed in MySQL mode. Why does this happen? Are there any syntax differences between them shown in this case? Thanks.

delete from Person
where Id not in (
select temp.minimum from 
(select min(Id) as minimum from Person group by Email) as temp
);
11
  • Yeah. SQL is not SQL - it is likely the most NOT standardized langauge ever created. In practice every product has a very different dialect. Commented Feb 20, 2020 at 14:07
  • 2
    I thought the MS SQL syntax looked OK. It also checks up all OK in SSMS Commented Feb 20, 2020 at 14:10
  • . . . . What Internal Error you got ? Commented Feb 20, 2020 at 14:14
  • Probably just an issue on the leetcode side Commented Feb 20, 2020 at 14:15
  • 1
    @60221611 This triply-nested query is really bad - it forces a full table scan to calculate the GROUP BY and HAVING, then another seek (I hope) to find the rows to delete. The "accepted" solution in leetcode does a full self-join on email, which could be quite clean. In MySQL 8/SQL Server, the CTE and ROW_Number will find the non-duplicates in a single pass. You'll have to compare exeuction plans for both queries (accepted and ROW_NUMBER) to find which is best Commented Feb 20, 2020 at 14:24

3 Answers 3

1

In SQL Server you use CTE with ROW_NUMBER() :

WITH cte AS (
     SELECT P.*, ROW_NUMBER() OVER (PARTITION BY p.email ORDER BY id) AS seq
     FROM Person P
)
DELETE
FROM cte c
WHERE c.seq > 1;

However, your original version of query should also work in SQL Server.

Sign up to request clarification or add additional context in comments.

1 Comment

Does this work? It is DELETEing from the pseuo-table created by WITH (cte).
0

Looks good to me. Perhaps

DELETE FROM Person
WHERE Id not in ( Select Id FROM
      (SELECT Email,  
        MIN(Id) as Id, COUNT(*) as N 
        FROM Person 
        GROUP BY Email
        HAVING COUNT(*) > 1) as temp
);

Make sure to run the inner SELECT by itself to see it's the same schema.

Comments

0

I tried this on sql server express 10.50.6560 and it seems it works...

CREATE TABLE PERSON
(
  ID INT NOT NULL
, EMAIL VARCHAR(1000)
)

ALTER TABLE PERSON
ADD CONSTRAINT PK_PERSON
PRIMARY KEY (ID)


INSERT INTO PERSON VALUES(1, 'AAAAA')
INSERT INTO PERSON VALUES(2, 'AAAAA')
INSERT INTO PERSON VALUES(3, 'BBBBB')

DROP TABLE PERSON

--Your query

delete from Person
where Id not in (
select temp.minimum from 
(select min(Id) as minimum from Person group by Email) as temp
);

It deletes one row...

Hope it helps

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.