最近在论坛中的MS Sql Server版块经常看到网友求助如何从一组数据集中获取每个类型中的某个字段最大的一条记录或者最新记录,首先大家都会想到采用group关键字分组,再利用max()函数获取最大的一条记录,但这样只能返回分组的字段,不能返回所有的字段,因此我在这里提供一种解决方法。
创建表语句
USE [master] GO /****** Object: Table [dbo].[Table_1] Script Date: 08/05/2013 13:21:28 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[Table_1]( [id] [int] NOT NULL, [pid] [int] NOT NULL, [op_type] [varchar](50) NOT NULL, [op_time] [datetime] NULL, [op_man] [varchar](50) NULL ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO
向表中插入测试数据
insert into [master].[dbo].[Table_1] ([id],[pid],[op_type],[op_time],[op_man]) values( 1 , 1 , '手动' , '2013-03-05 00:00:00.000' , 'A' ); insert into [master].[dbo].[Table_1] ([id],[pid],[op_type],[op_time],[op_man]) values( 2 , 1 , '自动' , '2013-05-05 00:00:00.000' , 'B' ); insert into [master].[dbo].[Table_1] ([id],[pid],[op_type],[op_time],[op_man]) values( 3 , 2 , '手动' , '2013-06-06 00:00:00.000' , 'A' ); insert into [master].[dbo].[Table_1] ([id],[pid],[op_type],[op_time],[op_man]) values( 4 , 1 , '手动' , '2013-06-06 00:00:00.000' , 'A' ); insert into [master].[dbo].[Table_1] ([id],[pid],[op_type],[op_time],[op_man]) values( 5 , 1 , '自动' , '2013-06-07 00:00:00.000' , 'A' ); insert into [master].[dbo].[Table_1] ([id],[pid],[op_type],[op_time],[op_man]) values( 6 , 2 , '自动' , '2013-06-07 00:00:00.000' , 'B' );
用select语句查询得到的结果
期望结果
开始我们都会采用分组和聚合函数的方式
SELECT [pid],max([op_time]) as op_time FROM [master].[dbo].[Table_1] group by pid
但这样得到的结果只能包含pid和op_time字段,不能包含这个表中所有的字段,因此我这里提供一种方法,对每个pid的数据进行排序,然后再取第一个
select * from ( SELECT t.*,ROW_NUMBER() over (partition by t.pid order by t.op_time desc) num FROM [master].[dbo].[Table_1] t ) a where num=1 GO