Cách lấy hàng MAX


20

Trong SQL Server, tôi luôn cảm thấy khó khăn khi lấy các hàng tối đa cho tập dữ liệu, tôi đang tìm một danh sách các phương thức để truy xuất các hàng tối đa với một số hướng dẫn về hiệu suất và khả năng bảo trì.

Bảng mẫu:

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', convert(datetime, '03/03/1976', 103), '234'  UNION ALL
SELECT 'Jane', convert(datetime, '13/06/1996', 103), '345' UNION ALL
SELECT 'Fred', convert(datetime, '14/02/1982', 103), '456' UNION ALL
SELECT 'Bob', convert(datetime, '25/10/1983', 103), '567' UNION ALL
SELECT 'Jane', convert(datetime, '12/04/1995', 103), '678' UNION ALL
SELECT 'Fred', convert(datetime, '03/03/1976', 103), '789'

select * from @Test

Cung cấp:

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

Nếu tôi muốn lấy thông tin đầy đủ về người (nhóm theo tên) đầy đủ nhất, tôi có thể sử dụng phương pháp nào?

Kết quả mong muốn:

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

Câu trả lời:


20

Hai phương pháp thông thường: tổng hợp và chức năng xếp hạng.

Tổng hợp hoạt động trên SQL Server 2000. Cả hai cách đều có thể sử dụng CTE hoặc bảng dẫn xuất

Đối với hiệu suất, tôi đã tìm thấy tổng hợp hoạt động tốt hơn. Tuy nhiên, có vẻ như các chức năng xếp hạng SQL Server 2008 chạy tốt hơn nhiều so với SQL Server 2005. Tôi chưa sử dụng SQL Server 2008 hàng ngày (công ty dinsoaur lớn) nên không thể nhận xét.

Có 2 câu hỏi SO liên quan nhưng hiện tại tôi không thể tìm thấy chúng. Một là câu hỏi về IO logic cao với các chức năng xếp hạng, một câu hỏi khác là kiểm tra xếp hạng trong các nhận xét qua SQL 2k5 so với 2k8. Lấy làm tiếc.

--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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.