2011-01-10 12 views
5

के आधार पर वर्गीकृत आंकड़ों से नीचे मैं का उपयोग कर SQL सर्वर 2005 प्रत्येक लिंक्ड ID के लिए एक निर्धारित तिथि के सबसे नजदीक रिकॉर्ड चयन करने की आवश्यकता:T-SQL - निकटतम तिथि के अनुसार चयन करें और आईडी

ID  Date  Linked ID 
........................... 
1 2010-09-02  25 
2 2010-09-01  25 
3 2010-09-08  39 
4 2010-09-09  39 
5 2010-09-10  39 
6 2010-09-10  34 
7 2010-09-29  34 
8 2010-10-01  37 
9 2010-10-02  36 
10 2010-10-03  36 

तो 2010/01/10 का उपयोग कर लौट जाना उन्हें चुनने:

1 2010-09-02  25 
5 2010-09-10  39 
7 2010-09-29  34 
8 2010-10-01  37 
9 2010-10-02  36 

मैं जानता हूँ कि यह possi होना चाहिए खून, लेकिन मेरे सिर को गोल करने के लिए प्रतीत नहीं होता है (दिन के अंत के करीब भी होना चाहिए: पी) यदि कोई मुझे सही दिशा में एक कोमल झुंड में मदद या दे सकता है तो इसकी सराहना की जाएगी!

संपादित करें: इसके अलावा, मैं इस एसक्यूएल सामने आने वाले निकटतम तिथि पाने के लिए:

abs(DATEDIFF(minute, Date_Column, '2010/10/01')) 

लेकिन समझ नहीं सकता कैसे क्वेरी ठीक से में शामिल करना ...

धन्यवाद

+0

जोड़ें ... आप मेरी टिप्पणी के बाद संपादन में जोड़ा। ठीक है, मैं आपको पूरी क्वेरी लिखूंगा। – Hogan

+0

आपका शीर्षक भ्रामक है, शायद यह "निकटतम दिनांक से आईडी आईडी का चयन करें" – dvhh

+0

आपका उदाहरण मिनट का उपयोग करके मिनट का उपयोग कर रहा है क्योंकि डेटीफ के पहले पैराम शायद काम नहीं करेंगे (क्योंकि आपके पास अपनी उदाहरण तिथियों में समय नहीं है।) आप उपयोग करना चाहते हैं दिन - जो abbr हो सकता है। 'दिन',' dd', या 'd' के रूप में। दिलचस्प बात यह है कि सभी उत्तर एक अलग abbr का उपयोग करें। – Hogan

उत्तर

8

देखो तो आप इस कोशिश कर सकते हैं कर सकते हैं।

DECLARE @Date DATE = '10/01/2010'; 

WITH cte AS 
    (
    SELECT ID, LinkedID, ABS(DATEDIFF(DD, @date, DATE)) diff, 
     ROW_NUMBER() OVER (PARTITION BY LinkedID ORDER BY ABS(DATEDIFF(DD, @date, DATE))) AS SEQUENCE 
    FROM MyTable 
    ) 

SELECT * 
FROM cte 
WHERE SEQUENCE = 1 
ORDER BY ID 
; 

आपने यह इंगित नहीं किया कि आप उस मामले को कैसे संभालना चाहते हैं जहां एक लिंक किए गए समूह में एकाधिक पंक्तियां लक्ष्य दिनांक के सबसे नज़दीक का प्रतिनिधित्व करती हैं। इस समाधान में केवल एक पंक्ति शामिल होगी और, इस मामले में आप गारंटी नहीं दे सकते कि एकाधिक मान्य मानों की कौन सी पंक्ति शामिल है।

यदि आप निकटतम मूल्य का प्रतिनिधित्व करने वाली सभी पंक्तियां शामिल करना चाहते हैं तो आप क्वेरी में ROWK() के साथ ROW_NUMBER() को बदल सकते हैं।

+0

यह मेरी क्वेरी (केवल एक चयन) से अच्छा है लेकिन मेरा शुरुआत शुरुआती के लिए स्पष्ट हो सकता है ... – Hogan

+0

ROW_NUMBER() पर अधिक जानकारी यहां उपलब्ध है: http://msdn.microsoft.com/en-us/library/ms186734.aspx –

+0

@ होगन - मुझे यकीन नहीं है कि मैं सहमत हूं। अगर आप जा रहे हैं किसी भी तरह से एक सीटीई का उपयोग करें, तो आप Row_Number() – Thomas

4

आप दिनों से DATEDIFF फ़ंक्शन (http://msdn.microsoft.com/en-us/library/ms189794.aspx) के पूर्ण मूल्य को देखना चाहते हैं।

क्वेरी कुछ इस तरह (नहीं परीक्षण किया)

with absDates as 
(
    select *, abs(DATEDIFF(day, Date_Column, '2010/10/01')) as days 
    from table 
), mdays as 
( 
    select min(days) as mdays, linkedid 
    from absDates 
    group by linkedid 
) 
select * 
from absdates 
inner join mdays on absdays.linkedid = mdays.linkedid and absdays.days = mdays.mdays 
+0

@ होगन आह हाँ मैं पहले से ही इसमें आया हूं, लेकिन इसका उल्लेख करना भूल गया सवाल में, इसलिए मैंने इसे अपडेट किया है। – w69rdy

+0

@ w69rdy का उल्लेख करने के लिए धन्यवाद: उदाहरण क्वेरी जोड़ा गया। – Hogan

+0

उदाहरण क्वेरी सही नहीं हो सकती है - यह न्यूनतम (दिन) होनी चाहिए, अन्यथा आप सबसे बड़ा अंतर वापस कर देंगे, है ना? साथ ही, मुझे नहीं लगता कि इस पर प्रदर्शन बहुत अच्छा होगा। आम तौर पर मैं ROW_NUMBER() समाधान का उपयोग करने की अनुशंसा करता हूं। यह अधिक सरल और अधिक प्रदर्शन होना चाहिए। –

0

तुम भी चयन बयान में एक सबक्वेरी के साथ यह करने के लिए कोशिश कर सकते हैं:

select [LinkedId], 
     (select top 1 [Date] from [Table] where [LinkedId]=x.[LinkedId] order by abs(DATEDIFF(DAY,[Date],@date))) 
from [Table] X 
group by [LinkedId] 
+0

वाह, यह def है। कम से कम प्रदर्शन - प्रत्येक लिंकिड के लिए एक चयन। – Hogan

+0

हां, यह सिर्फ छोटी टेबल के लिए है – pcofre

संबंधित मुद्दे