ये दो प्रश्न उस धारणा पर निर्भर करते हैं जो 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
, तो क्वेरीज़ काम नहीं करेंगी। यहाँ उस मामले के लिए एक समाधान है, भले ही यह काफी अंतराल और द्वीप तकनीक नहीं है कि इट्ज़िक बेन-गण जैसे कोई व्यक्ति सपने देखने में सक्षम हो सकता है, और भले ही यह ओपी के परिदृश्य के लिए प्रासंगिक न हो - यह हो सकता है भविष्य के पाठक के लिए प्रासंगिक है। यह थोड़ा अधिक जटिल है, और मैंने एक अतिरिक्त चर भी जोड़ा है - 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
है कि भोजन से कोई लेना-देना नहीं है?