Найти ближайшую дату в SQL Server

sql sql-server date

68800 просмотра

4 ответа

У меня есть таблица, dbo.Xс DateTime column Yкоторой могут быть сотни записей.

У моей хранимой процедуры есть параметр @CurrentDate, я хочу узнать в приведенной column Yвыше таблице дату, dbo.Xкоторая меньше и ближайшая к@CurrentDate.

Как это найти?

Автор: MaxRecursion Источник Размещён: 12.11.2019 09:11

Ответы (4)


65 плюса

Решение

Предложение where будет соответствовать всем строкам с датой, меньшей @CurrentDate, и, поскольку они упорядочены по убыванию, ТОП 1 будет ближайшей датой к текущей дате.

SELECT TOP 1 *
FROM x
WHERE x.date < @CurrentDate
ORDER BY x.date DESC
Автор: ederbf Размещён: 24.12.2012 03:36

13 плюса

Используйте DateDiff и упорядочите свой результат по количеству дней или секунд между этой датой и тем, что было

Что-то вроде этого

    select top 1 rowId, dateCol, datediff(second, @CurrentDate, dateCol) as SecondsBetweenDates
    from myTable
    where dateCol < @currentDate
    order by datediff(second, @CurrentDate, dateCol)
Автор: Mikey Mouse Размещён: 24.12.2012 03:33

1 плюс

У меня есть лучшее решение этой проблемы, я думаю.

Я покажу несколько изображений для поддержки и объясню окончательное решение.

Фон В моем решении у меня есть таблица курсов валют. Они представляют рыночные курсы для разных валют. Однако у нашего поставщика услуг возникли проблемы с подачей тарифов, поэтому некоторые тарифы имеют нулевые значения. Я хочу заполнить недостающие данные курсами для той же валюты, которые как можно ближе по времени к отсутствующему курсу. В основном я хочу получить RateId для ближайшей ненулевой ставки, которую я затем заменю. (Это не показано здесь в моем примере.)

1) Итак, для начала давайте определим информацию о пропущенных ставках:

Запрос, показывающий мои пропущенные ставки, т.е. имеет нулевое значение ставки

2) Далее давайте определим показатели, которые не пропали. Запрос с указанием не пропущенных ставок

3) В этом запросе происходит волшебство. Здесь я сделал предположение, которое можно удалить, но которое было добавлено для повышения эффективности / производительности запроса. Предположение в строке 26 состоит в том, что я ожидаю найти замещающую транзакцию в тот же день, что и транзакция с отсутствующим / нулевым значением. Волшебство происходит в строке 23: функция Row_Number добавляет автоматический номер, начинающийся с 1, для кратчайшей разницы во времени между отсутствующей и отсутствующей транзакцией. Следующая ближайшая транзакция имеет значение 2 и т. Д.

Обратите внимание, что в строке 25 я должен объединить валюты, чтобы не нарушать типы валют. То есть я не хочу заменять валюту AUD значениями 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
Автор: Craig Gers Размещён: 05.01.2018 12:36

-6 плюса

CREATE PROCEDURE CurrentDate
@CurrentDate DATETIME
AS
BEGIN
    Select * from orders
    where OrderDate < @CurrentDate
END
GO
Автор: user1583384 Размещён: 24.12.2012 03:54
32x32