Запрос на выбор значения в зависимости от даты

У меня есть таблица с обменными курсами, которые обновляются только тогда, когда приходит новый обменный курс, то есть фиксируется только дата ввода нового курса. однако у системы есть логика, чтобы сказать, если какая-либо дата попадает в определенную дату, она выбирает соответствующий обменный курс.

я хотел бы иметь запрос, который выбирает требуемый обменный курс с учетом любой предоставленной даты, т. е. выбирает курс из периода.

WITH ListDates(AllDates) AS
(    SELECT cast('2015-11-01' as date) AS DATE
    UNION ALL
    SELECT DATEADD(DAY,1,AllDates)
    FROM ListDates 
    WHERE AllDates < getdate())
SELECT  ld.AllDates,cr.effective_from,cr.rate_against_base
FROM ListDates ld
left join CurrencyRatetable cr on cr.effective_from between cr.effective_from and ld.alldates
option (maxrecursion 0)

Предоставление данных вместо их изображений помогает гораздо быстрее получать рекомендации от сообщества. Это одна из причин, по которой вы получаете отрицательный голос.

RF1991 17.01.2023 06:40

Используйте BETWEEN x and y и убедитесь, что дата x лишена всех данных о времени, а дата y не имеет времени ни на секунду за пределами диапазона, потому что значения здесь являются инклюзивными.

T.S. 17.01.2023 06:52
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
3
60
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я думаю, вы можете захотеть добиться требуемого результата, используя оконную функцию LEAD. Следуя примеру:

DECLARE @t TABLE(effective_from date, rate_against_base decimal(19,4))

INSERT INTO @t VALUES
('2000-01-01', 1.6)
,('2016-10-26', 1)
,('2020-07-13', 65.8765);

DECLARE @searchDate DATE = '2023-01-17';

WITH cte AS(
SELECT effective_from
      ,ISNULL(LEAD(effective_from) OVER (ORDER BY effective_from), CAST('2049-12-31' AS DATE)) AS effective_to
      ,rate_against_base
  FROM @t
)
SELECT rate_against_base
  FROM cte
  WHERE @searchDate >= effective_from
    AND @searchDate < effective_to
Ответ принят как подходящий

Вы можете использовать CROSS APPLY или OUTER APPLY вместе с подзапросом TOP 1.

Что-то вроде:

WITH ListDates(AllDates) AS (
    SELECT cast('2015-11-01' as date) AS DATE
    UNION ALL
    SELECT DATEADD(DAY,1,AllDates)
    FROM ListDates 
    WHERE AllDates < getdate()
)
SELECT ld.AllDates, cr.effective_from, cr.rate_against_base
FROM ListDates ld
OUTER APPLY (
    SELECT TOP 1 *
    FROM CurrencyRatetable cr
    WHERE cr.effective_from <= ld.alldates
    ORDER BY cr.effective_from DESC
) cr
ORDER BY ld.AllDates
option (maxrecursion 0)

И CROSS APPLY, и OUTER APPLY похожи на соединение с подзапросом. Разница в том, что CROSS APPLY похоже на внутреннее соединение, а OUTER APPLY — на левое соединение.

Убедитесь, что у CurrencyRatetable есть индекс Effective_from для эффективного доступа.

Смотрите эту скрипку db<>.

Другие вопросы по теме