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

时间:2016-03-08 02:56:18

标签: sql sql-server tsql

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

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

如果我的列是:ID |工作中心|注意| LOG_DATE

我将如何做到这一点?

我的代码只给了我整个表的最新音符条目,但我想要每个工作中心一个。

这就是我现在所拥有的:

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

2 个答案:

答案 0 :(得分: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,然后将它们连接到表。

答案 1 :(得分:0)

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;