sql-server – 如何获取MAX行

前端之家收集整理的这篇文章主要介绍了sql-server – 如何获取MAX行前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
sql Server中,我总是发现获取数据集的最大行很痛苦,我正在寻找一些方法列表来检索最大行,并提供有关性能和可维护性的一些指导.

样本表:

DECLARE @Test TABLE (ID INT IDENTITY(1,1),name VARCHAR(50),dateOfBirth DATETIME,TaxNumber varchar(10))

INSERT INTO @Test (name,dateOfBirth,TaxNumber)
SELECT 'Fred',convert(datetime,'25/01/1976',103),'123' UNION ALL
SELECT 'Bob','03/03/1976','234'  UNION ALL
SELECT 'Jane','13/06/1996','345' UNION ALL
SELECT 'Fred','14/02/1982','456' UNION ALL
SELECT 'Bob','25/10/1983','567' UNION ALL
SELECT 'Jane','12/04/1995','678' UNION ALL
SELECT 'Fred','789'

select * from @Test

得到:

ID          name      dateOfBirth             TaxNumber
----------- --------- ----------------------- ----------
1           Fred      1976-01-25 00:00:00.000 123
2           Bob       1976-03-03 00:00:00.000 234
3           Jane      1996-06-13 00:00:00.000 345
4           Fred      1982-02-14 00:00:00.000 456
5           Bob       1983-10-25 00:00:00.000 567
6           Jane      1995-04-12 00:00:00.000 678
7           Fred      1976-03-03 00:00:00.000 789

如果我想要检索最老的人(按名称分组)完整的详细信息,我可以使用哪些方法

期望的输出

ID          name      dateOfBirth             TaxNumber
----------- --------- ----------------------- ----------
1           Fred      1976-01-25 00:00:00.000 123
2           Bob       1976-03-03 00:00:00.000 234
6           Jane      1995-04-12 00:00:00.000 678

解决方法

两种常用方法:聚合和排名功能.

聚合适用于sql Server 2000.两种方式都可以使用CTE或派生表

为了性能,我发现聚合效果更好.但是,看起来sql Server 2008排名功能的运行远远好于sql Server 2005.我不是日常使用sql Server 2008(大型dinsoaur公司)所以无法发表评论.

有两个相关的SO问题,但我目前找不到它们.一个是关于具有排名功能的高逻辑IO的问题,另一个是关于sql 2k5与2k8的评论中的排名测试.抱歉.

--aggregate + CTE
;WITH cOldest AS
(
    SELECT name,MIN(dateOfBirth) AS MinDOB FROM @Test GROUP BY name
)
SELECT
    T.*
FROM
    @Test T
    JOIN
    cOldest C ON T.name = C.name AND T.dateOfBirth = C.MinDOB
ORDER BY
    T.ID

--aggregate + derived table
SELECT
    T.*
FROM
    @Test T
    JOIN
    (
    SELECT name,MIN(dateOfBirth) AS MinDOB FROM @Test GROUP BY name
    ) C ON T.name = C.name AND T.dateOfBirth = C.MinDOB
ORDER BY
    T.ID

--ranking + CTE
;WITH cOldest AS
(
    SELECT *,ROW_NUMBER() OVER (PARTITION BY name ORDER BY dateOfBirth) AS rnDOB FROM @Test
)
SELECT
    C.*
FROM
    cOldest C
WHERE
    C.rnDOB = 1
ORDER BY
    C.ID

--ranking + derived table
SELECT
    C.*
FROM
    (SELECT *,ROW_NUMBER() OVER (PARTITION BY name ORDER BY dateOfBirth) AS rnDOB FROM @Test) C
WHERE
    C.rnDOB = 1
ORDER BY
    C.ID

猜你在找的MsSQL相关文章