在TSql中使用分区进行分组 [英] Grouping with partition and over in TSql

查看:144
本文介绍了在TSql中使用分区进行分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的表格

  CREATE TABLE [dbo]。[Tooling](
[Id] [ int] IDENTITY(1,1)NOT NULL,
[Name] [nvarchar](50)NOT NULL,
[Status] [int] NOT NULL,
[DateFinished] [datetime] NULL,
[Tooling] [nvarchar](50)NULL,
[Updated] [datetime] NULL,

)ON [PRIMARY]

以下值

  SET IDENTITY_INSERT [工具] [工具] ON 

GO
INSERT [dbo]。[Tooling]([Id],[Name],[Status],[DateFinished],[Tooling], [更新])VALUES(1,N'Large',0,NULL,NULL,CAST(N'2015-05-05 00:00:00.000'AS DateTime))
GO
INSERT [dbo ] [工具]([Id],[Name],[Status],[DateFinished],[Tooling],[Updated])VALUES(2,N'Large',1,NULL,N'1',CAST N'2015-05-10 00:00:00.000'AS DateTime))
GO
INSERT [dbo]。[Tooling]([Id],[Name],[Status],[DateFinished] ,[Tooling],[Updated])VALUES(3,N'Small',0,NULL,N'2',CAST(N'2015-05-11 00:0) 0:00.000'AS DateTime))
GO
INSERT [dbo]。[Tooling]([Id],[Name],[Status],[DateFinished],[Tooling],[Updated]) VALUES(4,N'Large',2,NULL,N'1',CAST(N'2015-05-12 00:00:00.000'AS DateTime))
GO
INSERT [dbo] 。[Tooling]([Id],[Name],[Status],[DateFinished],[Tooling],[Updated])VALUES(5,N'Large',2,NULL,N'2',CAST(N '2015-05-12 00:00:00'000'AS DateTime))
GO
INSERT [dbo]。[Tooling]([Id],[Name],[Status],[DateFinished], [Tooling],[Updated])VALUES(6,N'Large',1,NULL,N'1',CAST(N'2015-05-13 00:00:00.000'AS DateTime))
GO
INSERT [dbo]。[Tooling]([Id],[Name],[Status],[DateFinished],[Tooling],[Updated])VALUES(7,N'Large',1,NULL, N'2',CAST(N'2015-05-14 00:00:00.000'AS DateTime))
GO
INSERT [dbo]。[Tooling]([Id],[Name],数值(8,N'Small',1,CAST(N'2015-05-15 00:00:00.000'AS DateTime),N'2' ,CAST(N'2015-0 5-15 00:00:00.000'AS DateTime))
GO
SET IDENTITY_INSERT [dbo]。[Tooling] OFF

我想创建一个看起来像是一个完全拥有的表的视图。

  SELECT ID,Name,Status,DateFinished 
FROM Tooling t by t.id

如果我运行的话,我希望排除ID为5和7的记录应该被排除,因为它们不会改变从前一行中选择的集合。
我有一个想法,通过使用分区
上的ROW_NUMBER()来解决这个问题,并且通过使用group by但是那似乎是不正确的(不能让它工作)

如果应该根据值更改对其进行分组,而不是其包含的值,那么如何对它进行分组?
任何建议来解决这个问题?
我的最终目标也是尝试将它转换为实体...

解决方案

好吧,假设它是有序的通过id

  select * 
from(
select *,rng = row_number()over(partition by grp order by id)
from(
select *,grp = row_number()over(order by id) - row_number()over(按名称分区,状态,DateFinished by id)
从工具)g
)gn
其中rng = 1
按ID编号


I have a simple table

CREATE TABLE [dbo].[Tooling](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Status] [int] NOT NULL,
[DateFinished] [datetime] NULL,
[Tooling] [nvarchar](50) NULL,
[Updated] [datetime] NULL,

 ) ON [PRIMARY]

with following values

SET IDENTITY_INSERT [dbo].[Tooling] ON 

GO
INSERT [dbo].[Tooling] ([Id], [Name], [Status], [DateFinished], [Tooling], [Updated]) VALUES (1, N'Large', 0, NULL, NULL, CAST(N'2015-05-05 00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Tooling] ([Id], [Name], [Status], [DateFinished], [Tooling], [Updated]) VALUES (2, N'Large', 1, NULL, N'1', CAST(N'2015-05-10 00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Tooling] ([Id], [Name], [Status], [DateFinished], [Tooling], [Updated]) VALUES (3, N'Small', 0, NULL, N'2', CAST(N'2015-05-11 00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Tooling] ([Id], [Name], [Status], [DateFinished], [Tooling], [Updated]) VALUES (4, N'Large', 2, NULL, N'1', CAST(N'2015-05-12 00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Tooling] ([Id], [Name], [Status], [DateFinished], [Tooling], [Updated]) VALUES (5, N'Large', 2, NULL, N'2', CAST(N'2015-05-12 00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Tooling] ([Id], [Name], [Status], [DateFinished], [Tooling], [Updated]) VALUES (6, N'Large', 1, NULL, N'1', CAST(N'2015-05-13 00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Tooling] ([Id], [Name], [Status], [DateFinished], [Tooling], [Updated]) VALUES (7, N'Large', 1, NULL, N'2', CAST(N'2015-05-14 00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Tooling] ([Id], [Name], [Status], [DateFinished], [Tooling], [Updated]) VALUES (8, N'Small', 1, CAST(N'2015-05-15 00:00:00.000' AS DateTime), N'2', CAST(N'2015-05-15 00:00:00.000' AS DateTime))
GO
SET IDENTITY_INSERT [dbo].[Tooling] OFF

I want to create a view of the table that looks like its an entirely own table.

SELECT         Id, Name, Status, DateFinished
FROM          Tooling t order by t.id

If i run that I would like that the records with id 5 and 7 should be excluded since they dont change in the selected set from the previous row. I had an idea to solve this by using, ROW_NUMBER() over partition And by using group by but thats seems to incorrect(Could not to get it to work at all)

How do I group it when the should be grouped on that the value change and not the value it contains? Any suggestions to solve this? My end goal is also try to convert this to linq to entities...

解决方案

OK, supposing it's ordered by id

select * 
from (
  select *, rng = row_number() over (partition by grp order by id)
  from (
    select *, grp = row_number() over (order by id) - row_number() over (partition by Name, Status, DateFinished order by id)
    from tooling ) g
  ) gn
where rng = 1
order by id

这篇关于在TSql中使用分区进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆