แบบสอบถามทั้งสองนี้ขึ้นอยู่กับสมมติฐานที่Taco_value
เพิ่มขึ้นตลอดเวลา
;WITH x AS
(
SELECT Taco_ID, Taco_date,
dr = ROW_NUMBER() OVER (PARTITION BY Taco_ID, Taco_Value ORDER BY Taco_date),
qr = ROW_NUMBER() OVER (PARTITION BY Taco_ID ORDER BY Taco_date)
FROM dbo.Taco
), y AS
(
SELECT Taco_ID, Taco_date,
rn = ROW_NUMBER() OVER (PARTITION BY Taco_ID, dr ORDER BY qr DESC)
FROM x WHERE dr = 1
)
SELECT Taco_ID, Taco_date
FROM y
WHERE rn = 1;
ทางเลือกที่มีความบ้าคลั่งของฟังก์ชั่นหน้าต่างน้อยลง:
;WITH x AS
(
SELECT Taco_ID, Taco_value, Taco_date = MIN(Taco_date)
FROM dbo.Taco
GROUP BY Taco_ID, Taco_value
), y AS
(
SELECT Taco_ID, Taco_date,
rn = ROW_NUMBER() OVER (PARTITION BY Taco_ID ORDER BY Taco_date DESC)
FROM x
)
SELECT Taco_ID, Taco_date FROM y WHERE rn = 1;
ตัวอย่างที่SQLfiddle
ปรับปรุง
สำหรับการติดตามนั้นมีการโต้เถียงกันว่าจะเกิดอะไรขึ้นหากTaco_value
สามารถทำซ้ำได้ หากสามารถไปได้ตั้งแต่ 1 ถึง 2 จากนั้นกลับเป็น 1 สำหรับTaco_ID
การสอบถามใด ๆแบบสอบถามจะไม่ทำงาน นี่เป็นวิธีแก้ปัญหาสำหรับกรณีนี้แม้ว่าจะไม่ใช่เทคนิคช่องว่างและเกาะที่คนอย่าง Itzik Ben-Gan อาจฝันถึงและแม้ว่ามันจะไม่เกี่ยวข้องกับสถานการณ์ของ OP ก็ตาม เกี่ยวข้องกับผู้อ่านในอนาคต มันซับซ้อนกว่านี้เล็กน้อยและฉันยังเพิ่มตัวแปรเพิ่มเติม - Taco_ID
ซึ่งมีเพียงหนึ่งตัวTaco_value
เท่านั้น
หากคุณต้องการรวมแถวแรกสำหรับ ID ใด ๆ ที่ค่าไม่เปลี่ยนแปลงในชุดทั้งหมด:
;WITH x AS
(
SELECT *, rn = ROW_NUMBER() OVER
(PARTITION BY Taco_ID ORDER BY Taco_date DESC)
FROM dbo.Taco
), rest AS (SELECT * FROM x WHERE rn > 1)
SELECT
main.Taco_ID,
Taco_date = MIN(CASE
WHEN main.Taco_value = rest.Taco_value
THEN rest.Taco_date ELSE main.Taco_date
END)
FROM x AS main LEFT OUTER JOIN rest
ON main.Taco_ID = rest.Taco_ID AND rest.rn > 1
WHERE main.rn = 1
AND NOT EXISTS
(
SELECT 1 FROM rest AS rest2
WHERE Taco_ID = rest.Taco_ID
AND rn < rest.rn
AND Taco_value <> rest.Taco_value
)
GROUP BY main.Taco_ID;
หากคุณต้องการยกเว้นแถวเหล่านั้นมันซับซ้อนกว่าเล็กน้อย แต่ยังคงมีการเปลี่ยนแปลงเล็กน้อย:
;WITH x AS
(
SELECT *, rn = ROW_NUMBER() OVER
(PARTITION BY Taco_ID ORDER BY Taco_date DESC)
FROM dbo.Taco
), rest AS (SELECT * FROM x WHERE rn > 1)
SELECT
main.Taco_ID,
Taco_date = MIN(
CASE
WHEN main.Taco_value = rest.Taco_value
THEN rest.Taco_date ELSE main.Taco_date
END)
FROM x AS main INNER JOIN rest -- ***** change this to INNER JOIN *****
ON main.Taco_ID = rest.Taco_ID AND rest.rn > 1
WHERE main.rn = 1
AND NOT EXISTS
(
SELECT 1 FROM rest AS rest2
WHERE Taco_ID = rest.Taco_ID
AND rn < rest.rn
AND Taco_value <> rest.Taco_value
)
AND EXISTS -- ***** add this EXISTS clause *****
(
SELECT 1 FROM rest AS rest2
WHERE Taco_ID = rest.Taco_ID
AND Taco_value <> rest.Taco_value
)
GROUP BY main.Taco_ID;
อัปเดตตัวอย่าง SQLfiddle
taco
ไม่มีอะไรเกี่ยวข้องกับอาหารเหรอ?