2010-09-27 32 views
6

Tiếp theo/sao chép computhomas's question, nhưng thêm một số xoắn ...MSSQL: Chỉ mục cuối cùng trong GROUP BY (với id)

Tôi đã theo bảng dưới đây trong MSSQL2008

id | business_key | result | date 
1 | 1 | 0 | 9 
2 | 1 | 1 | 8 
3 | 2 | 1 | 7 
4 | 3 | n | 6 
5 | 4 | 1 | 5 
6 | 4 | 0 | 4 

Và bây giờ tôi muốn nhóm dựa trên business_key trả lại mục nhập đầy đủ với ngày mới nhất. Vì vậy, kết quả mong đợi của tôi là:

id | business_key | result | date 
1 | 1 | 0 | 9 
3 | 2 | 1 | 7 
4 | 3 | n | 6 
5 | 4 | 1 | 5 

Tôi cũng đặt cược rằng có một cách để đạt được điều đó, tôi chỉ không thể tìm thấy/xem/nghĩ về nó vào lúc này.

chỉnh sửa: xin lỗi về điều này, tôi thực sự có ý nghĩa khác với câu hỏi ban đầu tôi đã làm. Tôi cảm thấy như chỉnh sửa điều này có thể tốt hơn là chấp nhận một giải pháp và đưa ra một câu hỏi khác. vấn đề ban đầu của tôi là tôi không lọc theo id.

+0

Không chắc cách này là đáng kể khác nhau từ câu hỏi computhomas của. – wcm

+0

@wcm hoàn toàn đồng ý, tôi đã xây dựng nó rất tệ. chỉnh sửa ... xin vui lòng chỉnh sửa câu trả lời của bạn là tốt, và xin lỗi một lần nữa! – cregox

Trả lời

15
SELECT t.* 
FROM 
(
    SELECT *, ROW_NUMBER() OVER 
       (
        PARTITION BY [business_key] 
        ORDER BY [date] DESC 
      ) AS [RowNum] 
    FROM yourTable 
) AS t 
WHERE t.[RowNum] = 1 
+0

điều này chỉ hoạt động! bây giờ tôi phải hiểu tại sao ...: D – cregox

+0

nó hoạt động bởi vì hàm Row_Number trả về một và chỉ một 1 cho mỗi nhóm. Thú vị sử dụng chức năng tổng hợp đó. Tôi thích: +1 – wcm

2

Làm thế nào về (sửa sau khi thay đổi câu hỏi):

with latestdate as (
    select business_key, maxdate=max(date) 
    from the_table 
    group by business_key 
), latest as (
    select ID = max(id) 
    from the_table 
    inner join latestdate 
    on the_table.business_key=latestdate.business_key 
     and the_table.date=latestdate.maxdate 
    group by the_table.business_key 
) 
select the_table.* 
from the_table 
    inner join latest 
    on latest.id=the_table.id 
+0

sự khác biệt về việc sử dụng 'with' hoặc chỉ cần chèn' được chọn 'sau khi' nối kết bên trong' là gì? dù sao, có vẻ như mất khá nhiều thời gian để chạy *, và có lẽ tốt hơn nên thay thế 'bên trong' bằng' phải'… Nhưng điều này dường như ** hoạt động! Cảm ơn rất nhiều, ** wcm **! Tôi đang cố gắng để tinh chỉnh nó vào trường hợp phức tạp của tôi, tho - không quá chắc chắn nếu điều này sẽ làm việc cho lĩnh vực duy nhất của tôi là * id *. – cregox

+0

Bạn đã lập chỉ mục trường ngày và trường business_key cùng nhau chưa? Hoặc được coi là một chỉ số nhóm? – wcm

+0

Xin lỗi, để trả lời câu hỏi thực tế của bạn. Trong trường hợp này, có lẽ không có nhiều khác biệt. Tất nhiên kế hoạch thực hiện là bạn của bạn. Hãy thử cả hai (hoặc một biến thể trên @LittleBobbyTables trả lời trước khi chỉnh sửa ban đầu) và chọn một trong đó là hiệu suất nhất. Nhiều như tôi thích có câu trả lời được chọn, giải pháp của họ có thể là tốt nhất cho bạn. – wcm

3
SELECT 
     * 
FROM 
     mytable 
WHERE 
     ID IN (SELECT MAX(ID) FROM mytable GROUP BY business_key) 
+0

Cách của bạn có thể dễ hiểu hơn. Tôi giống như CTE. – wcm

+0

ok, điều này làm cho tôi thấy tôi cần phải xây dựng lại câu hỏi ... bạn có nghĩ rằng tôi nên chỉnh sửa nó hay tạo một câu hỏi khác không? – cregox

+0

Không thể biết trừ khi chúng ta thấy nó khác nhau như thế nào. Nếu nó chỉ là một sự tinh tế nhỏ, hãy thêm câu hỏi mới vào văn bản hiện tại. – egrunin

2
SELECT 
    MAX(T1.id) AS [id], 
    T1.business_key, 
    T1.result 
FROM 
    dbo.My_Table T1 
LEFT OUTER JOIN dbo.My_Table T2 ON 
    T2.business_key = T1.business_key AND 
    T2.id > T1.id 
WHERE 
    T2.id IS NULL 
GROUP BY T1.business_key, 
    T1.result 
ORDER BY MAX(T1.id) 

sửa dựa trên làm rõ

SELECT M1.* 
FROM My_Table M1 
INNER JOIN 
(
    SELECT [business_key], MAX([date]) as MaxDate 
    FROM My_Table 
    GROUP BY [business_key] 
) M2 ON M1.business_key = M2.business_key AND M1.[date] = M2.MaxDate 
ORDER BY M1.[id] 
+0

về cơ bản giống như của wcm. vì vậy, cảm ơn bạn đã xác nhận! :) – cregox

+0

Yup - nó có thêm lợi ích khi làm việc trong SQL 2000 vì nó không phải là một CTE (cho chúng tôi schlubs nghèo bị mắc kẹt trong năm 2000), nhưng tôi prefe CTE phiên bản bản thân mình. – LittleBobbyTables

+0

và CTE là gì? – cregox

2

Giả sự kết hợp của ngày business_key & là duy nhất sau đó ....

dụ làm việc (lần thứ 3 là một nét duyên dáng):

declare @src as table(id int, business_key int,result int,[date] int) 
insert into @src 
SELECT 1,1,0,9 
UNION SELECT 2,1,1,8 
UNION SELECT 3,2,1,7 
UNION SELECT 4,3,1,6 
UNION SELECT 5,4,1,5 
UNION SELECT 6,4,0,4 

;with bkdate(business_key,[date]) 
AS 
(
    select business_key,MAX([date]) 
    from @src 
    group by business_key 
) 
select src.* from @src src 
inner join bkdate 
ON src.[date] = bkdate.date 
and src.business_key = bkdate.business_key 
order by id 
+0

bạn cần thêm một kết nối vào business_key vào cuối SQL của bạn. – wcm

+0

yêu thích phần làm việc! nhưng điều này chỉ hoạt động nếu bạn xem xét ngày duy nhất - thường không đúng đối với ngày tháng cũng như trường hợp của tôi, trong đó chỉ có id là duy nhất. – cregox

+0

bây giờ điều này thậm chí còn đẹp hơn ... nhưng tôi có cùng một vấn đề như với câu trả lời của wcm. 2070 hàng. – cregox