Wednesday, July 20, 2011

SQL: Lấy dữ liệu dòng cuối cùng trong mỗi group

Bài toán này đặt ra trong trường hợp khi bảng dữ liệu có từ hai khóa chính (primary key) trở lên, trong đó yêu cầu xác định dữ liệu sao cho một khóa chính nào đó là duy nhất và lớn nhất.

Bài toán: Ta có bảng Table1 với dữ liệu như sau:
Col1 (PK)
Col2
(PK)
Col3
(PK)
Col4
A
1
1
A_1_1
A
1
2
A_1_2
A
2
2
A_2_2
A
2
4
A_2_4
B
1
4
B_1_4
B
1
5
B_1_5
C
1
3
C_1_3
C
2
6
C_2_6
C
2
7
C_2_7
C
2
9
C_2_9
Bây giờ, vấn đề đặt ra là làm thế nào để nhóm dữ liệu theo Col1Col2, sau đó lấy thêm dữ liệu của Col3Col4 sao cho Col3 là lớn nhất trong mỗi dòng dữ liệu mà tôi muốn có.
Kết quả sẽ như sau:
Col1
Col2
Col3
Col4
A
1
2
A_1_2
A
2
4
A_2_4
B
1
5
B_1_5
C
1
3
C_1_3
C
2
9
C_2_9
Giải pháp trong trường hợp này có thể viết như sau:
SELECT T1.*
FROM Table1 T1 LEFT JOIN Table1 T2
    ON  T1.Col1 = T2.Col1
    AND T1.Col2 = T2.Col2
    AND T1.Col3 < T2.Col3
WHERE T2.Col3 IS NULL;     
Giải thích: Để giải thích cho câu lệnh trên, ta có thể sử dụng câu lệnh như sau:
SELECT T1.Col1, T1.Col2, T1.Col3, T2.Col1, T2.Col2, T2.Col3
FROM Table1 T1 LEFT JOIN Table1 T2
    ON T1.Col1 = T2.Col1
    AND T1.Col2 = T2.Col2
    AND T1.Col3 < T2.Col3;
Kết quả sẽ như sau:
Col1
Col2
Col3
Col1
Col2
Col3
A
1
1
A
1
2
A
1
2
A
1
NULL
A
2
2
A
2
4
A
2
4
A
2
NULL
B
1
4
B
1
5
B
1
5
B
1
NULL
C
1
3
C
1
NULL
C
2
6
C
2
7
C
2
6
C
2
9
C
2
7
C
2
9
C
2
9
C
2
NULL
Với điều kiện LEFT JOIN là T1.Col3 < T2.Col3, với mỗi nhóm (T1.Col1, T1.Col2), T1.Col3 là lớn nhất thì T2.Col3 sẽ là NULL.
Do đó, khi bổ sung thêm điều kiện sau khi LEFT JOIN là T2.Col3 IS NULL thì ta sẽ lấy được kết quả mong muốn.

No comments:

Post a Comment