2012-10-17 29 views
16

thể trùng lặp:
How to get the record of a table who contains the maximum value?SQL select max (ngày) và giá trị tương ứng

Tôi đã có một truy vấn tổng hợp như sau:

SELECT TrainingID, Max(CompletedDate) as CompletedDate, Max(Notes) as Notes  --This will only return the longest notes entry 
FROM HR_EmployeeTrainings ET 
WHERE (ET.AvantiRecID IS NULL OR ET.AvantiRecID = @avantiRecID) 
GROUP BY AvantiRecID, TrainingID    

Đó là làm việc, và trả về dữ liệu chính xác hầu hết thời gian, nhưng tôi nhận thấy một vấn đề. Trường Ghi chú được trả lại sẽ không nhất thiết khớp với bản ghi mà giá trị tối đa (completeDate) là từ. Thay vào đó, nó sẽ là một chuỗi dài nhất? Hoặc cái có giá trị ASCII cao nhất? SQL Server làm gì trong trường hợp liên kết giữa hai bản ghi? Tôi thậm chí không chắc chắn. Những gì tôi muốn nhận được là trường ghi chú từ bản ghi tối đa (completeDate). Làm thế nào tôi nên nhận được về việc này?

+0

Đã hoàn thànhNgày không phải là Ngày giờ? – Frobzig

+0

Đây là một DateTime. Không có vấn đề với lĩnh vực đó, nhưng với Ghi chú. – MAW74656

+0

ghi chú tối đa hoặc mọi ghi chú cho 'max (completedDate)'? – Marc

Trả lời

23

Bạn có thể sử dụng một subquery. Truy vấn con sẽ nhận được Max(CompletedDate). Sau đó, bạn lấy giá trị này và tham gia lại vào bảng của mình để truy xuất liên kết ghi chú với ngày đó:

select ET1.TrainingID, 
    ET1.CompletedDate, 
    ET1.Notes 
from HR_EmployeeTrainings ET1 
inner join 
(
    select Max(CompletedDate) CompletedDate, TrainingID 
    from HR_EmployeeTrainings 
    --where AvantiRecID IS NULL OR AvantiRecID = @avantiRecID 
    group by TrainingID 
) ET2 
    on ET1.TrainingID = ET2.TrainingID 
    and ET1.CompletedDate = ET2.CompletedDate 
where ET1.AvantiRecID IS NULL OR ET1.AvantiRecID = @avantiRecID 
3

Không có cách nào dễ dàng để làm điều này, nhưng một cái gì đó như thế này sẽ làm việc:

SELECT ET.TrainingID, 
    ET.CompletedDate, 
    ET.Notes 
FROM 
HR_EmployeeTrainings ET 
inner join 
(
    select TrainingID, Max(CompletedDate) as CompletedDate 
    FROM HR_EmployeeTrainings 
    WHERE (ET.AvantiRecID IS NULL OR ET.AvantiRecID = @avantiRecID) 
    GROUP BY AvantiRecID, TrainingID 
) ET2 
    on ET.TrainingID = ET2.TrainingID 
    and ET.CompletedDate = ET2.CompletedDate 
+0

cú pháp của bạn sai đối với truy vấn phụ của bạn, bạn thiếu mệnh đề 'FROM'. – Taryn

3

Mỗi hàm MAX được đánh giá riêng lẻ. Vì vậy, MAX (CompletedDate) sẽ trả về giá trị của cột CompletedDate mới nhất và MAX (Ghi chú) sẽ trả lại giá trị tối đa (tức là thứ tự chữ cái cao nhất).

Bạn cần phải cấu trúc truy vấn của mình khác nhau để có được những gì bạn muốn. Câu hỏi này đã thực sự đã được hỏi và trả lời nhiều lần, vì vậy tôi sẽ không lặp lại nó:

How to find the record in a table that contains the maximum value?

Finding the record with maximum value in SQL

+1

Nếu câu hỏi đã được trả lời nhiều lần trước, điều đúng đắn cần làm là bỏ phiếu để đóng "trùng lặp chính xác" – Tony

+0

Thx, tôi đã thực hiện điều đó. – Marplesoft

5

À đúng rồi, đó là cách nó được thiết kế trong SQL. Bạn nhận được tối đa của mỗi cột một cách riêng biệt. Có vẻ như bạn muốn trả về các giá trị từ hàng có ngày tối đa, vì vậy bạn phải chọn hàng có ngày tối đa. Tôi thích làm điều này với một subselect, như các truy vấn giữ nhỏ gọn dễ đọc.

SELECT TrainingID, CompletedDate, Notes 
FROM HR_EmployeeTrainings ET 
WHERE (ET.AvantiRecID IS NULL OR ET.AvantiRecID = @avantiRecID) 
AND CompletedDate in 
    (Select Max(CompletedDate) from HR_EmployeeTrainings B 
    where B.TrainingID = ET.TrainingID) 

Nếu bạn cũng muốn khớp với AntiRecID, bạn cũng nên bao gồm trong lựa chọn này.

Các vấn đề liên quan