Tôi đang xử lý một bảng Postgres (được gọi là "cuộc sống") chứa bản ghi với các cột cho time_stamp, usr_id, transaction_id và lives_remaining. Tôi cần một truy vấn sẽ cung cấp cho tôi tổng số lives_remaining gần đây nhất cho mỗi usr_id
- Có nhiều người dùng (usr_id's riêng biệt)
- time_stamp không phải là mã định danh duy nhất: đôi khi các sự kiện của người dùng (từng hàng trong bảng) sẽ xảy ra với cùng time_stamp.
- trans_id là duy nhất chỉ trong phạm vi thời gian rất nhỏ: theo thời gian nó lặp lại
- còn lại_lives (cho một người dùng nhất định) có thể tăng và giảm theo thời gian
thí dụ:
time_stamp | lives_remaining | usr_id | trans_id ----------------------------------------- 07:00 | 1 | 1 | 1 09:00 | 4 | 2 | 2 10h00 | 2 | 3 | 3 10h00 | 1 | 2 | 4 11h00 | 4 | 1 | 5 11h00 | 3 | 1 | 6 13:00 | 3 | 3 | 1
Vì tôi sẽ cần truy cập các cột khác của hàng với dữ liệu mới nhất cho mỗi usr_id nhất định, tôi cần một truy vấn đưa ra kết quả như sau:
time_stamp | lives_remaining | usr_id | trans_id ----------------------------------------- 11h00 | 3 | 1 | 6 10h00 | 1 | 2 | 4 13:00 | 3 | 3 | 1
Như đã đề cập, mỗi usr_id có thể được hoặc mất mạng, và đôi khi các sự kiện có dấu thời gian này xảy ra gần nhau đến mức chúng có cùng dấu thời gian! Do đó, truy vấn này sẽ không hoạt động:
SELECT b.time_stamp,b.lives_remaining,b.usr_id,b.trans_id FROM
(SELECT usr_id, max(time_stamp) AS max_timestamp
FROM lives GROUP BY usr_id ORDER BY usr_id) a
JOIN lives b ON a.max_timestamp = b.time_stamp
Thay vào đó, tôi cần sử dụng cả time_stamp (đầu tiên) và trans_id (thứ hai) để xác định hàng chính xác. Sau đó, tôi cũng cần chuyển thông tin đó từ truy vấn con đến truy vấn chính sẽ cung cấp dữ liệu cho các cột khác của các hàng thích hợp. Đây là truy vấn hack mà tôi phải làm việc:
SELECT b.time_stamp,b.lives_remaining,b.usr_id,b.trans_id FROM
(SELECT usr_id, max(time_stamp || '*' || trans_id)
AS max_timestamp_transid
FROM lives GROUP BY usr_id ORDER BY usr_id) a
JOIN lives b ON a.max_timestamp_transid = b.time_stamp || '*' || b.trans_id
ORDER BY b.usr_id
Được rồi, vì vậy điều này hiệu quả, nhưng tôi không thích nó. Nó yêu cầu một truy vấn trong một truy vấn, một liên kết tự và đối với tôi, dường như nó có thể đơn giản hơn nhiều bằng cách lấy hàng mà MAX tìm thấy có dấu thời gian và trans_id lớn nhất. Bảng "sống" có hàng chục triệu hàng để phân tích cú pháp, vì vậy tôi muốn truy vấn này nhanh nhất và hiệu quả nhất có thể. Tôi mới sử dụng RDBM và Postgres nói riêng, vì vậy tôi biết rằng tôi cần phải sử dụng hiệu quả các chỉ mục thích hợp. Tôi hơi mất cách để tối ưu hóa.
Tôi tìm thấy một cuộc thảo luận tương tự ở đây . Tôi có thể thực hiện một số loại Postgres tương đương với một hàm phân tích của Oracle không?
Bất kỳ lời khuyên nào về việc truy cập thông tin cột liên quan được sử dụng bởi một hàm tổng hợp (như MAX), tạo chỉ mục và tạo các truy vấn tốt hơn sẽ được đánh giá cao!
PS Bạn có thể sử dụng phần sau để tạo trường hợp ví dụ của tôi:
create TABLE lives (time_stamp timestamp, lives_remaining integer,
usr_id integer, trans_id integer);
insert into lives values ('2000-01-01 07:00', 1, 1, 1);
insert into lives values ('2000-01-01 09:00', 4, 2, 2);
insert into lives values ('2000-01-01 10:00', 2, 3, 3);
insert into lives values ('2000-01-01 10:00', 1, 2, 4);
insert into lives values ('2000-01-01 11:00', 4, 1, 5);
insert into lives values ('2000-01-01 11:00', 3, 1, 6);
insert into lives values ('2000-01-01 13:00', 3, 3, 1);