ฉันมีอินพุตต่อไปนี้:
id | value
----+-------
1 | 136
2 | NULL
3 | 650
4 | NULL
5 | NULL
6 | NULL
7 | 954
8 | NULL
9 | 104
10 | NULL
ฉันคาดหวังผลลัพธ์ต่อไปนี้:
id | value
----+-------
1 | 136
2 | 136
3 | 650
4 | 650
5 | 650
6 | 650
7 | 954
8 | 954
9 | 104
10 | 104
วิธีแก้ปัญหาเล็กน้อยจะเข้าร่วมตารางที่มี<
ความสัมพันธ์แล้วเลือกMAX
ค่าใน a GROUP BY
:
WITH tmp AS (
SELECT t2.id, MAX(t1.id) AS lastKnownId
FROM t t1, t t2
WHERE
t1.value IS NOT NULL
AND
t2.id >= t1.id
GROUP BY t2.id
)
SELECT
tmp.id, t.value
FROM t, tmp
WHERE t.id = tmp.lastKnownId;
อย่างไรก็ตามการประมวลผลเล็กน้อยของรหัสนี้จะสร้างตารางภายในของการนับจำนวนแถวของตารางอินพุต ( O (n ^ 2) ) ฉันคาดว่า t-sql จะปรับมันให้เหมาะสม - ในระดับบล็อก / บันทึกงานที่ต้องทำนั้นง่ายมากและเป็นเส้นตรงโดยพื้นฐานคือสำหรับลูป ( O (n) )
อย่างไรก็ตามในการทดลองของฉัน MS SQL 2016 ล่าสุดไม่สามารถปรับให้เหมาะสมกับแบบสอบถามนี้ได้อย่างถูกต้องทำให้แบบสอบถามนี้ไม่สามารถดำเนินการสำหรับตารางอินพุตขนาดใหญ่
นอกจากนี้แบบสอบถามต้องทำงานอย่างรวดเร็วทำให้โซลูชันเคอร์เซอร์ที่ใช้ง่าย (แต่แตกต่างกันมาก) เป็นไปไม่ได้
การใช้ตารางชั่วคราวที่ได้รับการสนับสนุนจากหน่วยความจำอาจเป็นการประนีประนอมที่ดี แต่ฉันไม่แน่ใจว่าจะสามารถทำงานได้เร็วขึ้นอย่างมากหรือไม่พิจารณาว่าแบบสอบถามตัวอย่างของฉันที่ใช้แบบสอบถามย่อยไม่ทำงาน
ฉันยังคิดที่จะขุดฟังก์ชั่นหน้าต่างบางส่วนจากเอกสาร t-sql สิ่งที่อาจถูกหลอกให้ทำสิ่งที่ฉันต้องการ ตัวอย่างเช่นผลรวมสะสมกำลังทำคล้ายกันมาก แต่ฉันไม่สามารถหลอกให้องค์ประกอบที่ไม่ใช่โมฆะล่าสุดและไม่รวมผลรวมขององค์ประกอบก่อนหน้านี้
ทางออกที่ดีที่สุดคือการสืบค้นอย่างรวดเร็วโดยไม่ต้องใช้รหัสขั้นตอนหรือตารางชั่วคราว อีกวิธีหนึ่งโซลูชันที่มีตารางชั่วคราวก็ไม่เป็นไร แต่การทำซ้ำขั้นตอนของตารางจะไม่เป็นเช่นนั้น