ฉันกำลังจัดการกับตาราง Postgres (เรียกว่า "ชีวิต") ที่มีระเบียนที่มีคอลัมน์สำหรับ time_stamp, usr_id, transaction_id และ lives_remaining ฉันต้องการคำค้นหาที่จะให้ผลรวม life_remaining ล่าสุดสำหรับ usr_id แต่ละรายการ
- มีผู้ใช้หลายคน (usr_id ต่างกัน)
- time_stamp ไม่ใช่ตัวระบุที่ไม่ซ้ำกัน: บางครั้งเหตุการณ์ของผู้ใช้ (ทีละแถวในตาราง) จะเกิดขึ้นพร้อมกับ time_stamp เดียวกัน
- trans_id จะไม่ซ้ำกันสำหรับช่วงเวลาที่เล็กมากเท่านั้น: เมื่อเวลาผ่านไปจะเกิดซ้ำ
- ส่วนที่เหลือ (สำหรับผู้ใช้ที่ระบุ) สามารถเพิ่มและลดได้เมื่อเวลาผ่านไป
ตัวอย่าง:
time_stamp | lives_remaining | usr_id | trans_id ----------------------------------------- 07:00 | 1 | 1 | 1 09:00 | 4 | 2 | 2 10:00 | 2 | 3 | 3 10:00 | 1 | 2 | 4 11:00 | 4 | 1 | 5 11:00 | 3 | 1 | 6 13:00 | 3 | 3 | 1
เนื่องจากฉันจะต้องเข้าถึงคอลัมน์อื่น ๆ ของแถวพร้อมข้อมูลล่าสุดสำหรับแต่ละ usr_id ที่กำหนดฉันต้องการแบบสอบถามที่ให้ผลลัพธ์ดังนี้:
time_stamp | lives_remaining | usr_id | trans_id ----------------------------------------- 11:00 | 3 | 1 | 6 10:00 | 1 | 2 | 4 13:00 | 3 | 3 | 1
ดังที่ได้กล่าวไว้ usr_id แต่ละรายการสามารถได้รับหรือเสียชีวิตและบางครั้งเหตุการณ์ที่ประทับเวลาเหล่านี้เกิดขึ้นใกล้กันมากจนมีการประทับเวลาเดียวกัน! ดังนั้นการสืบค้นนี้จะใช้ไม่ได้:
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
แต่ฉันต้องใช้ทั้ง time_stamp (ครั้งแรก) และ trans_id (วินาที) เพื่อระบุแถวที่ถูกต้อง จากนั้นฉันต้องส่งข้อมูลนั้นจากแบบสอบถามย่อยไปยังแบบสอบถามหลักซึ่งจะให้ข้อมูลสำหรับคอลัมน์อื่น ๆ ของแถวที่เหมาะสม นี่คือข้อความค้นหาที่ถูกแฮ็กที่ฉันได้รับ:
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
โอเคมันใช้ได้ แต่ฉันไม่ชอบ มันต้องมีการสืบค้นภายในแบบสอบถามการเข้าร่วมด้วยตนเองและสำหรับฉันแล้วดูเหมือนว่ามันอาจจะง่ายกว่ามากโดยการจับแถวที่ MAX พบว่ามีการประทับเวลาและ trans_id ที่ใหญ่ที่สุด ตาราง "ชีวิต" มีแถวให้แยกวิเคราะห์หลายสิบล้านแถวดังนั้นฉันจึงอยากให้คำค้นหานี้รวดเร็วและมีประสิทธิภาพมากที่สุด ฉันเพิ่งเริ่มใช้ RDBM และ Postgres โดยเฉพาะดังนั้นฉันจึงรู้ว่าฉันต้องใช้ดัชนีที่เหมาะสมอย่างมีประสิทธิภาพ ฉันหลงทางเล็กน้อยเกี่ยวกับวิธีการเพิ่มประสิทธิภาพ
ผมพบว่าการอภิปรายที่คล้ายกันที่นี่ ฉันสามารถใช้ Postgres บางประเภทที่เทียบเท่ากับฟังก์ชันการวิเคราะห์ของ Oracle ได้หรือไม่
คำแนะนำใด ๆ ในการเข้าถึงข้อมูลคอลัมน์ที่เกี่ยวข้องที่ใช้โดยฟังก์ชันรวม (เช่น MAX) การสร้างดัชนีและการสร้างแบบสอบถามที่ดีขึ้นจะได้รับการชื่นชมมาก!
ป.ล. คุณสามารถใช้สิ่งต่อไปนี้เพื่อสร้างกรณีตัวอย่างของฉัน:
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);