有没有办法删除表中除一个(随机)行之外的所有行,而没有在DELETE
语句中指定任何列名?
我正在尝试做这样的事情:
CREATE TABLE [dbo].[DeleteExceptTop1]([Id] INT)
INSERT [dbo].[DeleteExceptTop1] SELECT 1
INSERT [dbo].[DeleteExceptTop1] SELECT 2
INSERT [dbo].[DeleteExceptTop1] SELECT 3
SELECT * FROM [dbo].[DeleteExceptTop1]
DELETE
FROM [dbo].[DeleteExceptTop1]
EXCEPT
SELECT TOP 1 * FROM [dbo].[DeleteExceptTop1]
SELECT * FROM [dbo].[DeleteExceptTop1]
最终SELECT
应该产生一行(可以是三行中的任何一行)。
答案 0 :(得分:6)
;WITH CTE AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT newid())) AS RN
FROM [dbo].[DeleteExceptTop1]
)
DELETE FROM CTE
WHERE RN > 1
或类似于@ abatishchev的答案,但在排序方面有更多种类,并且避免使用弃用的构造。
DECLARE @C INT
SELECT @C = COUNT(*) - 1
FROM [dbo].[DeleteExceptTop1]
IF @c > 0
BEGIN
WITH CTE AS
(
SELECT TOP(@C) *
FROM [dbo].[DeleteExceptTop1]
ORDER BY NEWID()
)
DELETE FROM CTE;
END
或使用EXCEPT
的最终方式,并假设没有重复的行,并且所有列都是与EXCEPT
运算符兼容的数据类型
/*Materialise TOP 1 to ensure only evaluated once*/
SELECT TOP(1) *
INTO #T
FROM [dbo].[DeleteExceptTop1]
ORDER BY NEWID()
;WITH CTE AS
(
SELECT *
FROM [dbo].[DeleteExceptTop1] T1
WHERE EXISTS(
SELECT *
FROM #T
EXCEPT
SELECT T1.*)
)
DELETE FROM CTE;
DROP TABLE #T
答案 1 :(得分:3)
尝试:
declare @c int
select @c = count(*) - 1 from [dbo].[DeleteExceptTop1]
IF @c > 0
BEGIN
set RowCount @c
delete from [dbo].[DeleteExceptTop1]
END
答案 2 :(得分:2)
没有。
您需要使用列名(例如主键的名称)来标识要删除的行。
“随机行”在SQL中没有任何意义,除了它的数据。如果您要删除除某些行之外的所有内容,您必须将该行与您使用的其他行区分为DELETE
EXCEPT
通过比较行中的DISTINCT
值来工作。
编辑: 如果您可以指定主键,那么这是一件小事。您只需DELETE
PK <>
您的“随机”选择或 NOT IN
您的“随机”选择。
编辑:显然我错误地指定任何列名称,你可以使用指定的ROW_NUMBER
来做这件事。但是我我不会删除我的答案,因为它引用了您在评论中讨论过的EXCEPT
的使用。如果从<{1}}
答案 3 :(得分:1)
你可以这样做(SQL 2008)
DECLARE @Original TABLE ([Id] INT)
INSERT INTO @Original(ID) VALUES(1)
INSERT INTO @Original(ID) VALUES(2)
INSERT INTO @Original(ID) VALUES(3)
SELECT * FROM @Original;
WITH CTE AS
(SELECT ROW_NUMBER() OVER(ORDER BY ID) AS ROW, ID FROM @Original)
DELETE @Original
FROM @Original O
INNER JOIN CTE ON O.ID = CTE.ROW
WHERE ROW > 1
SELECT * FROM @Original
答案 4 :(得分:0)
似乎最简单的答案可能是最好的。以下应该有效:
Declare @count int
Set @count=(Select count(*) from DeleteExceptTop1)-1
Delete top (@count) from DeleteExceptTop1
答案 5 :(得分:0)
我知道它已被回答但是怎么样?
DELETE
FROM [dbo].[DeleteExceptTop1]
Where Id not in (
SELECT TOP 1 * FROM [dbo].[DeleteExceptTop1])