TSQL - 每组删除除 1 之外的所有行

Posted

技术标签:

【中文标题】TSQL - 每组删除除 1 之外的所有行【英文标题】:TSQL - Delete All Rows Except 1 Per Group 【发布时间】:2016-03-08 02:56:17 【问题描述】:

假设我有 5 个工作中心(工作中心 1、工作中心 2、工作中心 3、工作中心 4、工作中心 5)

每个工作中心都有几行按数据输入日期排序的注释。我想删除每个工作中心的所有行,最后输入的数据行除外。

如果我的列是:ID |工作中心 |注意 |日志_日期

我该怎么做呢?

我的代码只为我提供了整个表格的最新注释条目,但我希望每个工作中心都有一个。

这就是我现在拥有的:

DELETE FROM @Table
WHERE ID NOT IN (SELECT TOP 1 ID FROM @Table 
             GROUP BY Workcenter, ID 
             ORDER BY Log_Date DESC)

【问题讨论】:

【参考方案1】:

试试这个:

delete t1 from table t1 
where not exists
(select 1 from 
       (select workcenter,max(log_date)as log_date from table group by workcenter) t2  
       where t1.workcenter = t2.workcenter and t1.log_date = t2.log_date
)

使用 exists 子查询获取每个工作中心的最大 log_date,然后将它们连接到表。

【讨论】:

正是我需要的。谢谢。【参考方案2】:
using CTE we can achieve this:

;WITH cte AS
(SELECT ROW_NUMBER() OVER (PARTITION BY name ORDER BY createdate DESC ) AS rowno, * FROM workgroups)
DELETE FROM cte WHERE rowno !=1;

CREATE TABLE workgroups(id INT IDENTITY(1,1),name VARCHAR(50), createdate DATETIME DEFAULT GETDATE())

INSERT [dbo].[workgroups] ([id], [name], [createdate]) VALUES (1, N'workgroup1', CAST(0x0000A60F011F7840 AS DateTime))
INSERT [dbo].[workgroups] ([id], [name], [createdate]) VALUES (2, N'workgroup1', CAST(0x0000A60F011F7F8E AS DateTime))
INSERT [dbo].[workgroups] ([id], [name], [createdate]) VALUES (3, N'workgroup1', CAST(0x0000A60F011F8728 AS DateTime))
INSERT [dbo].[workgroups] ([id], [name], [createdate]) VALUES (4, N'workgroup2', CAST(0x0000A60F011F92B9 AS DateTime))
INSERT [dbo].[workgroups] ([id], [name], [createdate]) VALUES (5, N'workgroup2', CAST(0x0000A60F011F97C0 AS DateTime))
INSERT [dbo].[workgroups] ([id], [name], [createdate]) VALUES (6, N'workgroup3', CAST(0x0000A60F011FA443 AS DateTime))
INSERT [dbo].[workgroups] ([id], [name], [createdate]) VALUES (7, N'workgroup3', CAST(0x0000A60F011FA73B AS DateTime))
INSERT [dbo].[workgroups] ([id], [name], [createdate]) VALUES (8, N'workgroup3', CAST(0x0000A60F011FA9FB AS DateTime))

SELECT ROW_NUMBER() OVER (PARTITION BY name ORDER BY createdate DESC ) AS rowno, * FROM workgroups


;WITH cte AS
(SELECT ROW_NUMBER() OVER (PARTITION BY name ORDER BY createdate DESC ) AS rowno, * FROM workgroups)
DELETE FROM cte WHERE rowno !=1;

【讨论】:

以上是关于TSQL - 每组删除除 1 之外的所有行的主要内容,如果未能解决你的问题,请参考以下文章

删除除 Group 之外的所有 SQL 行

如何从表中删除除前两个和最后一个之外的所有行?

MS-ACCESS:删除除 top 1 之外的所有行并从查询中更新表

jQuery删除除第一行之外的所有表行

删除除给定查询获取的所有记录之外的所有记录

模式匹配并删除除最后一次出现的所有行