【问题标题】:Why this code works well in MySQL but not in SQL Server?为什么这段代码在 MySQL 中运行良好,但在 SQL Server 中运行良好?
【发布时间】:2020-06-04 21:15:58
【问题描述】:

这是 Leetcode 中的一个问题:https://leetcode.com/problems/delete-duplicate-emails/solution/

基本上,问题要求删除重复的电子邮件并保留索引最小的电子邮件。

我的代码如下,我先在SQL Server模式下运行,显示“Internal Error”。但它已经通过 MySQL 模式。为什么会这样?在这种情况下,它们之间是否存在语法差异?谢谢。

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

【问题讨论】:

  • 是的。 SQL 不是 SQL——它可能是有史以来最不标准化的语言。实际上,每种产品都有非常不同的方言。
  • 我认为 MS SQL 语法看起来不错。它还会检查 SSMS 中的一切正常
  • 。 . . . Internal Error 你得到了什么?
  • 可能只是 leetcode 方面的问题
  • @60221611 这个三重嵌套查询真的很糟糕——它强制进行全表扫描来计算 GROUP BY 和 HAVING,然后再寻找(我希望)找到要删除的行。 leetcode 中的“已接受”解决方案在 email 上进行了完全自联接,这可能非常干净。在 MySQL 8/SQL Server 中,CTE 和 ROW_Number 将一次性找到非重复项。您必须比较两个查询(已接受和 ROW_NUMBER)的执行计划,以找到最佳的执行计划

标签: mysql sql sql-server tsql


【解决方案1】:

我在 sql server express 10.50.6560 上试过这个,它似乎可以工作......

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

--您的查询

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

删除一行...

希望对你有帮助

【讨论】:

    【解决方案2】:

    我觉得不错。也许

    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
    );
    

    确保自己运行内部 SELECT 以查看它是相同的架构。

    【讨论】:

      【解决方案3】:

      SQL Server 中,您将CTEROW_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;
      

      但是,您的原始查询版本也应该可以在 SQL Server 中使用。

      【讨论】:

      • 这行得通吗?它是来自WITH (cte) 创建的伪表中的DELETEing
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多