繁体   English   中英

在SQL Server中查找最接近的日期

[英]Find closest date in SQL Server

我有一个表dbo.XDateTime column Y ,可能有数百条记录。

我的存储过程有参数@CurrentDate ,我想找出上面表dbo.X column Y的日期,该日期小于且最接近@CurrentDate.

怎么找到它?

where子句将匹配日期小于@CurrentDate的所有行,并且由于它们是后续排序的,因此TOP 1将是与当前日期最接近的日期。

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

使用DateDiff并按结果显示该日期与输入之间的天数或秒数

像这样的东西

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

我认为我有更好的解决方案。

我将展示一些图像来支持和解释最终的解决方案。

背景在我的解决方案中,我有一个外汇汇率表。 这些代表不同货币的市场汇率。 但是,我们的服务提供商在费率Feed方面存在问题,因此某些费率的值为零。 我想用相同货币的汇率填补缺失的数据,这些汇率最接近缺失的汇率。 基本上我想得到最接近的非零利率的RateId,然后我将替换。 (这在我的例子中没有显示。)

1)因此,开始时我们可以识别丢失的费率信息:

查询显示我的遗漏率,即费率值为零

2)接下来让我们确定不缺少的费率。 查询显示未丢失的费率

3)这个查询是神奇发生的地方。 我在这里做了一个假设,可以删除但添加它以提高查询的效率/性能。 第26行的假设是我希望在缺失/零交易的同一天找到替代交易。 神奇的事情发生在第23行:Row_Number函数添加一个从1开始的自动编号,用于缺失和非缺失事务之间的最短时间差。 下一个最接近的交易的rownum为2等。

请注意,在第25行,我必须加入货币,以便我不会使货币类型不匹配。 那就是我不想用CHF值替换澳元货币。 我想要最接近的匹配货币。

将两个数据集与row_number组合以标识最近的事务

4)最后,让我们获取RowNum为1 的数据最终查询

查询完整查询如下;

    ; 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
CREATE PROCEDURE CurrentDate
@CurrentDate DATETIME
AS
BEGIN
    Select * from orders
    where OrderDate < @CurrentDate
END
GO

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM