2012-12-24 10 views
18

में सबसे नज़दीकी तारीख खोजें मेरे पास dbo.X है DateTimecolumn Y जिसमें सैकड़ों रिकॉर्ड हो सकते हैं।SQL सर्वर

मेरे संग्रहित प्रक्रिया पैरामीटर @CurrentDate है, मैं उपरोक्त तालिका dbo.X में column Y में तारीख जो कम इसे कैसे खोजें @CurrentDate.

लिए और करीबी से है पता लगाना चाहते हैं?

उत्तर

48

जहां खंड की तारीख के साथ सभी पंक्तियों से भी कम समय की भरपाई कर देंगे @CurrentDate और, चूंकि उन्हें क्रमशः आदेश दिया जाता है, इसलिए शीर्ष 1 वर्तमान तिथि की सबसे नज़दीकी तारीख होगी।

SELECT TOP 1 * 
FROM x 
WHERE x.date < @CurrentDate 
ORDER BY x.date DESC 
+1

के लिए धन्यवाद लेकिन यह कितना कुशल है? – MaxRecursion

+1

डेटाबेस डिज़ाइन पर निर्भर करता है। मेरा सुझाव है कि आप दिनांक तालिका के लिए अपनी तालिका पर एक इंडेक्स सेट अप करने का प्रयास करें, इसलिए सिस्टम सीधे उस मान के लिए जा सकेगा जो क्वेरी से मेल खाता है। मदद के लिए – ederbf

+0

अच्छा धन्यवाद। – MaxRecursion

7

उपयोग DateDiff और अपने परिणाम के आदेश कितने दिन या सेकंड उस तारीख और क्या बीच हैं द्वारा इनपुट था

की तरह कुछ इस

select top 1 rowId, dateCol, datediff(second, @CurrentDate, dateCol) as SecondsBetweenDates 
    from myTable 
    where dateCol < @currentDate 
    order by datediff(second, @CurrentDate, dateCol) 
+3

आदेश द्वारा, आपके पास उनके उपनाम से स्तंभों को संदर्भित कर सकते हैं (यानी आप कर सकते हैं 'SecondsBetweenDate' द्वारा आदेश)। हालांकि, आप स्तंभों की बजाय अभिव्यक्तियों द्वारा पंक्तियों को क्रमबद्ध कर रहे हैं। यह क्वेरी को गैर-[सार योग्य] बनाने की संभावना है (http://en.wikipedia.org/wiki/Sargable "Sargable (विकिपीडिया)")। सिर्फ एक नोट। –

+0

@AndriyM आह, यह नहीं पता था, टिप –

-7
CREATE PROCEDURE CurrentDate 
@CurrentDate DATETIME 
AS 
BEGIN 
    Select * from orders 
    where OrderDate < @CurrentDate 
END 
GO 
-1

मैं इस समस्या मुझे लगता है कि के लिए एक बेहतर समाधान है।

मैं अंतिम समाधान का समर्थन और व्याख्या करने के लिए कुछ छवियां दिखाऊंगा।

पृष्ठभूमि मेरे समाधान में मेरे पास एफएक्स दरें हैं। ये विभिन्न मुद्राओं के लिए बाजार दरों का प्रतिनिधित्व करते हैं। हालांकि, हमारे सेवा प्रदाता को रेट फीड में कोई समस्या है और ऐसी कुछ दरों में शून्य मान हैं। मैं लापता डेटा को उसी मुद्रा के लिए दरों के साथ भरना चाहता हूं जो लापता दर के समय के सबसे नज़दीक है। असल में मैं रेटेड को निकटतम गैर शून्य दर के लिए प्राप्त करना चाहता हूं जिसे मैं बदल दूंगा। (यह यहां मेरी उदाहरण में दिखाया गया नहीं है।)

1) तो शुरू करने के लिए लापता दरों जानकारी की पहचान कर सकते हैं:

Query showing my missing rates i.e. have a rate value of zero

2) अगला कि लापता नहीं कर रहे हैं दरों को पहचान लेते हैं । Query showing rates that are not missing

3) यह क्वेरी वह जगह है जहां जादू होता है। मैंने यहां एक धारणा बनाई है जिसे हटाया जा सकता है लेकिन क्वेरी की दक्षता/प्रदर्शन में सुधार करने के लिए जोड़ा गया था। लाइन 26 पर धारणा यह है कि मुझे उसी दिन एक वैकल्पिक लेनदेन की उम्मीद है जो लापता/शून्य लेनदेन के रूप में है। जादू होता है लाइन 23 है: Row_Number फ़ंक्शन लापता और अनुपलब्ध लेनदेन के बीच सबसे कम समय के अंतर के लिए 1 से शुरू होने वाला एक ऑटो नंबर जोड़ता है। अगले निकटतम लेनदेन में 2 आदि का राउनम है

कृपया ध्यान दें कि लाइन 25 में मुझे मुद्राओं में शामिल होना चाहिए ताकि मैं मुद्रा प्रकारों को मेल नहीं खा सकूं। मैं सीएफ़ मूल्यों के साथ एक एयूडी मुद्रा को प्रतिस्थापित नहीं करना चाहता हूं। मैं निकटतम मिलान मुद्राओं चाहता हूँ।

Combining the two data sets with a row_number to identify nearest transaction

4) अंत में, की सुविधा देता है जहां ROWNUM है डेटा प्राप्त 1 The final query

क्वेरी पूर्ण क्वेरी इस प्रकार है;

; with cte_zero_rates as 
(
     Select  * 
     from  fxrates 
     where  (spot_exp = 0 or spot_exp = 0) 
), 
cte_non_zero_rates as 
(
     Select  * 
     from  fxrates 
     where  (spot_exp > 0 and spot_exp > 0) 
) 
,cte_Nearest_Transaction as 
(
     select  z.FXRatesID as Zero_FXRatesID 
        ,z.importDate as Zero_importDate 
        ,z.currency  as Zero_Currency 
        ,nz.currency as NonZero_Currency 
        ,nz.FXRatesID as NonZero_FXRatesID 
        ,nz.spot_imp 
        ,nz.importDate as NonZero_importDate 
        ,DATEDIFF(ss, z.importDate, nz.importDate) as TimeDifferece 
        ,ROW_NUMBER() Over(partition by z.FXRatesID order by abs(DATEDIFF(ss, z.importDate, nz.importDate)) asc) as RowNum 
     from  cte_zero_rates z 
     left join cte_non_zero_rates nz on nz.currency = z.currency 
        and cast(nz.importDate as date) = cast(z.importDate as date) 
     --order by z.currency desc, z.importDate desc 
) 
select   n.Zero_FXRatesID 
       ,n.Zero_Currency 
       ,n.Zero_importDate 
       ,n.NonZero_importDate 
       ,DATEDIFF(s, n.NonZero_importDate,n.Zero_importDate) as Delay_In_Seconds 
       ,n.NonZero_Currency 
       ,n.NonZero_FXRatesID 
from   cte_Nearest_Transaction n 
where   n.RowNum = 1 
       and n.NonZero_FXRatesID is not null 
order by  n.Zero_Currency, n.NonZero_importDate