Поиск курса валюты. SQL-запрос в Oracle.

Источник: foxbase

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

Постановка задачи:

Имеется таблица изменений курса валют T_CURRENCY:

CODE varchar2(32) Код валюты (USD, RUR, …)
DATE_C date Дата изменения курса
VALUE number Значение курса

Данные заносятся в эту таблицу каждый раз, когда изменяется значение курса какой либо валюты. Напишите SQL запрос, с помощью которого можно получить значение курса для заданной валюты на заданную дату.

Решение:

При решении этой задачи необходимо сообразить, что курсы валют изменяются не каждый день. Например, в выходные изменений нет, а запросить значение интересующей нас валюты мы можем на любую дату, в том числе и на любой выходной. Соответственно, простой запрос на равенство даты будет неправильным решением. Если это обстоятельство отметить при ответе, то задача может считаться наполовину решенной, так как этим вы продемонстрируете знание предметной области, что немаловажно. Если люди, проводящие собеседование, адекватные, то это уже будет большим плюсом.

Совсем будет неплохо, если мы в решении напишем DDL для создания нужной нам таблицы и определение первичного ключа, дополнительно продемонстрировав умение создавать таблицы скриптами, а не тупо при помощи какого-нибудь SQL Navigator-а:

create table T_CURRENCY

( CODE   varchar2(32) not null,

DATE_C date         not null,

VALUE  number       not null

);

alter table T_CURRENCY

add constraint PK_T_CURRENCY

primary key (CODE,DATE_C)

usingindexpctfree 0;

Данные для теста

insert into T_CURRENCY values ("USD",to_date("25.05.2009","DD.MM.YYYY"),31);

insert into T_CURRENCY values ("USD",to_date("26.06.2009","DD.MM.YYYY"),32);

insert into T_CURRENCY values ("USD",to_date("29.06.2009","DD.MM.YYYY"),30);

commit;

Далее следует немного подумать и реализовать запрос с учетом отмеченного выше обстоятельства. Классический вариант запроса с использованием подзапроса будет иметь вид:

select CODE, VALUE

from T_CURRENCY

where DATE_C = (select max(DATE_C)

from T_CURRENCY

where DATE_C <= to_date("27.06.2009","DD.MM.YYYY")

)

andCODE="USD";

Этот запрос выведет курс доллара  на заданную дату. В подзапросе мы ищем максимальную дату меньшую, чем заданную. Все же в ответе лучше будет написать запрос, используя переменные подстановки:

select CODE, VALUE

from T_CURRENCY

where DATE_C = (select max(DATE_C)

from T_CURRENCY

where DATE_C <= : DATE_C

)

andCODE= :CODE;

Можно также дополнительно написать вариант решения этой задачи, используя PL/SQL функцию, демонстрируя собственные знания:

create or replace

function GET_CURRENCY(psCODE in varchar2, - Кодвалюты

pdDATE in date      - Датаактуальности

) return number

is

begin

for i in (select VALUE

from T_CURRENCY

where CODE = psCODE

and DATE_C <= pdDATE

order by DATE_C desc

)

loop

return i.VALUE;

end loop;

return null;

end GET_CURRENCY;

С точки зрения производительности использование PL/SQL функции в этом виде более предпочтительно, чем использование запроса с подзапросом, так как в PL/SQL функции не требуется двойного сканирования таблицы с данными.


Страница сайта http://185.71.96.61
Оригинал находится по адресу http://185.71.96.61/home.asp?artId=23105