可以使用 HAVING 子句进行删除吗?

Posted

技术标签:

【中文标题】可以使用 HAVING 子句进行删除吗?【英文标题】:Possible to do a delete with a HAVING clause? 【发布时间】:2012-07-29 01:44:51 【问题描述】:

我想做如下的事情:

DELETE UserPredictions
  GROUP BY UserId
  HAVING COUNT(*) < 500

但是我遇到了语法错误。甚至可以在 SQL Server 中使用 HAVING 子句进行删除,还是我必须将计数汇总到 CTE 并使用连接进行删除?

【问题讨论】:

【参考方案1】:

不是真的。 have 子句意味着聚合,这意味着您不再拥有原始行。

我认为您想要以下内容:

DELETE from UserPredictions
where UserId in (select UserId from UserPredictions group by UserId having count(*) < 500)

【讨论】:

我明白你不能在 FROM 子句中指定目标表 'UserPredictions' 进行更新 @radtek。 . .据推测,您使用的是 mysql 而不是 SQL Server。 正确,我使用了 Zane Bien 的解决方案,在 MySQL 中工作,谢谢【参考方案2】:

您可以在DELETE 语句中使用连接子选择:

DELETE a
FROM   UserPredictions a
JOIN
(
    SELECT   UserId
    FROM     UserPredictions
    GROUP BY UserId
    HAVING   COUNT(1) < 500
) b ON a.UserId = b.UserId

SQLFiddle Demo

【讨论】:

【参考方案3】:

试试这个嵌套查询:

DELETE FROM UserPredictions  
WHERE UserId IN (SELECT UserId
                 FROM UserPredictions 
                 GROUP BY UserId
                 HAVING COUNT(*) < 500)

【讨论】:

【参考方案4】:

您可以使用row_number() OVER (partition by ) 和 CTE 做很多事情,但前提是您的 RDBMS 支持它。

例子:

WITH CTE AS 
(
    SELECT UserId,
    ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY UserId) AS rowcount    
    FROM UserPredictions
)
DELETE FROM CTE
WHERE rowcount < 500

关于行计数功能的其他信息:

https://docs.microsoft.com/en-us/sql/t-sql/functions/row-number-transact-sql?view=sql-server-2017

【讨论】:

【参考方案5】:

我不认为这是可能的,但是你可以试试这个

更新:Ininner join 都可以使用

Declare @Sample table 
(
UserID int,
col2 int
)
INSERT INTO @Sample
SELECT 1,50 UNION ALL
SELECT 1,100 UNION ALL
SELECT 2,150 UNION ALL
SELECT 2,200 union all
Select 4,500

DeLETE FROM @Sample  
WHERE UserID IN (SELECT UserID
             FROM @Sample 
             GROUP BY UserID
             HAVING COUNT(*) > 1)


 Delete O
 FROM @Sample O
 INNER JOIN 
 (
  SELECT UserID 
  FROM @Sample  
  GROUP BY UserID
 HAVING COUNT(*) >1
 ) X
ON O.UserID = X.UserID

我最初发布的答案:

Delete O
FROM UserPredictions O
INNER JOIN 
(
 SELECT UserID 
 FROM UserPredictions  
 GROUP BY UserID
 HAVING COUNT(*) <500
 ) X
ON O.UserID = X.UserID

【讨论】:

以上是关于可以使用 HAVING 子句进行删除吗?的主要内容,如果未能解决你的问题,请参考以下文章

对不在有子句中的列进行分组

MySQL?having子句

在SQL语句中同时包含where子句,groupby子句,having子句及聚集函数,将按照怎么样的顺序执行?

在oracle中where 子句和having子句中的区别

在oracle中where 子句和having子句中的区别

使用嵌套的 group-by/having 子句进行复杂连接?