2012-12-24 281 views
18

我有一個表dbo.XDateTimecolumn Y它可能有數百條記錄。在SQL Server中查找最近日期

我的存儲過程具有參數@CurrentDate,我想找出小於且最接近@CurrentDate.

如何找到它在上表dbo.Xcolumn Y的日期?

回答

48

where子句將匹配日期的所有行小於@CurrentDate,並且,由於它們是以後序排列的,所以TOP 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

在ORDER BY,則可以通過它們的別名引用列(即可以'ORDER BY SecondsBetweenDate')。但是,您正在按表達式對行進行排序而不是按列進行排序。這很可能會使查詢不可[sargable](http://en.wikipedia.org/wiki/Sargable「Sargable(Wikipedia)」)。只是一個筆記。 –

+0

@AndriyM啊,不知道,謝謝你的提示 –

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

我對這個問題,我認爲更好的解決方案。

我會展示一些圖片來支持和解釋最終的解決方案。

背景 在我的解決方案中,我有一個FX匯率表。這些代表不同貨幣的市場匯率。但是,我們的服務提供商在匯率上存在問題,因此一些匯率的價值爲零。我想填補缺失的數據,並以相同貨幣的匯率與最近的匯率進行比較。基本上我想獲得最接近的非零率的RateId,然後我將會替換它。 (這裏不顯示在我的例子。)

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等的rownum。

請注意,在第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