powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / SQL запрос - конвертация затрат в разных валютах в USD
16 сообщений из 16, страница 1 из 1
SQL запрос - конвертация затрат в разных валютах в USD
    #37190253
vill_ager
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
есть таблица с затратами в разных валютах: zatr (дата, код валюты, сумма)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
date        val  summa
 01 / 01 / 2011 , USD,  5000 
 01 / 01 / 2011 , EUR,  7000 
 02 / 01 / 2011 , USD,  3000 
 02 / 01 / 2011 , USD,  3000 
 03 / 01 / 2011 , USD,  1000 
и т.д.
есть таблица с курсами валют к рублю: valcurs
курсы валют вводятся на дату изменения, т.е.
Код: plaintext
1.
2.
3.
date       val curs
 01 / 01 / 2011 ,USD, 30 
 02 / 01 / 2011 ,USD, 31 
 04 / 01 / 2011 ,USD, 30 
курс на 3/01/2011 - 31

нужно привести все затраты к одной валюте (например USD) , с учетом курса на дату затрат

можно ли сделать это одним запросом, без ХП
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37190407
Naf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
варианты
1. хранить дату окончания действия курса
2.
Код: plaintext
1.
2.
3.
4.
5.
6.
select T.date, T.val, T.summa, T.summa*valcurs.curs as rubsumma
from
(select zatr.date, zatr.val, zatr.summa, max(valcurs.date) as maxdate
from zatr 
left join valcurs on (zatr.val=valcurs.val and zatr.date>=valcurs.date)
group by zatr.date, zatr.val, zatr.summa) as T
inner join valcurs on (T.val=valcurs.val and T.maxdate=valcurs.date)
3.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select zatr.date, zatr.val, zatr.summa, zatr.summa*T.curs as rubsumma
from zatr
left join
(select valcurs1.date as begindate, coalesce(min(valcurs2.date),дата_армагедона) as enddate, valcurs1.val, valcurs1.curs
from valcurs as valcurs1
left join valcurs as valcurs2
on valcurs1.val=valcurs2.val and valcurs1.date<valcurs2.date
group by valcurs1.date, valcurs1.val, valcurs1.curs) asT
on (zatr.date between T.begindate and T.enddate ) and (zatr.val=T.val)
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37190589
vill_ager
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Naf,

велик и могуч SQL

спасибо
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37190618
vill_ager
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
все хорошо, но в этот запрос еще бы курс USD вытянуть, чтобы rubsumma в USD перевести
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select T.date, T.val, T.summa,valcurs.curs, T.summa*valcurs.curs as rubsumma
from
	(
	select zatr.date, zatr.val, zatr.summa, max(valcurs.date) as maxdate
	from zatr 
	left join valcurs on (zatr.val=valcurs.val and zatr.date>=valcurs.date)
	group by zatr.date, zatr.val, zatr.summa
	) as T
inner join valcurs on (T.val=valcurs.val and T.maxdate=valcurs.date)
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37190642
Ivan Durak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vill_ager,

не правильно ты усд подтянул.
Его подтягивать надо сразу в подзапросе. чтобы иметь сумму в усд на КАЖДУЮ дату платежа.
А не один раз в конце!
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37190766
Naf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vill_agerвсе хорошо, но в этот запрос еще бы курс USD вытянуть, чтобы rubsumma в USD перевести
аналогично
мне больше вариант 1 нравится (хранить дату окончания действия курса)
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37190962
vill_ager
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Nafмне больше вариант 1 нравится (хранить дату окончания действия курса)
тогда каждый день придется корректировать дату
а так ввел и забыл до следующего изменения

Nafаналогично

:) легко сказать, у меня не получается
может потому, что курсы разных валют могут меняться в разные дни

если уточнить задачу -
нужно получить кросс-курс к USD на дату каждой операции
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37202868
Konstantin Permyakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vill_agerтогда каждый день придется корректировать дату
а так ввел и забыл до следующего изменения

А кто Вам мешает задать эту дату следующего изменения?
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37203527
vill_ager
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Konstantin Permyakov,

дата следующего изменения - по результатам торгов
изменения может и не быть

а если бы я знал результаты следующих торгов, то не шарился бы на этом форуме... :)

а запрос получился такой:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
select u.date, u.val, u.summa, u.curs, u.rubsumma,u.maxdate,
	val_cur.curs as cursUsd, u.rubsumma/val_cur.curs as usdsumma
from 
	(select R.date, R.summa,r.curs, R.val , max(val_cur.date) as maxdate,r.rubsumma 
	from 
		(select T.date, T.val,T.summa,val_cur.curs as curs, T.summa*val_cur.curs as rubsumma
		from
			(select zatr0.date, zatr0.val, zatr0.summa, max(val_cur.date) as maxdate
			from 
				(select date, sum(summa) as summa,val 
				from zatr  
				where date>='2011-01-01' and date<='2011-28-02'	
				group by date,val) as zatr0
				left join VAL_CUR on (zatr0.val=VAL_CUR.val and zatr0.date>=val_cur.date)
				group by zatr0.date, zatr0.val, zatr0.summa
			) as T
			inner join val_cur on (T.val=val_cur.val and T.maxdate=val_cur.date)
		) as R
		left join VAL_CUR on (R.date>=val_cur.date and val_cur.VAL= 3 )
	group by R.date, R.val, R.summa
	) as u
inner join val_cur on ( 3 =val_cur.val and u.maxdate=val_cur.date)

код USD-3
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37204128
Skoffer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я бы еще посоветовал не лезть за курсом к каждой записи... Найдите сразу курсы всех валют на сегодняшнее число и работайте с ними. Иначе при большом количестве строк в таблице затрат ваш запрос умрет.
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37204142
Skoffer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Обшибся, не усмотрел историю.
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37204210
vill_ager
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Skoffer,
так и есть, работает долго
в гонках победил вариант с обычным циклом
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37204516
Skoffer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хотел бы отметить еще что в первом запросе Naf, есть ошибка. Группируя по дате,валюте и сумме вы отсекаете все платежи в одной валюте за день c такой же суммой.
Т.е. если в zatr есть такие строчки

02/01/2011 USD 3000
02/01/2011 USD 3000

То внутренний подзапрос:

SELECT zatr.dt,
zatr.val,
zatr.summ,
MAX(valcurs.dt) AS maxdt
FROM zatr LEFT JOIN valcurs ON(zatr.val = valcurs.val
AND zatr.dt >= valcurs.dt)
GROUP BY zatr.dt,
zatr.val,
zatr.summ

Вернет:

02/01/2011 USD 3000, maxdt.

Не знаю есть в ли MYSQL скалярные подзапросы, а в Oracle я бы сделал так:

SELECT a.dt,
a.val,
a.summ,
b.curs
FROM
(SELECT zatr.dt,
zatr.val,
zatr.summ,
(SELECT MAX( valcurs.dt ) FROM valcurs WHERE valcurs.dt <= zatr.dt) as maxdt
FROM zatr) a, valcurs b

WHERE a.maxdt=b.dt and a.val=b.val;

И добавил бы индекс на дату в обоих таблицах. В таком случае оптимизатор будет искать max как
FIRST ROWS INDEX RANGE SCAN MIN/MAX.
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37204527
Skoffer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Но третий запрос Nafa все равно круче всего как оказалось )
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37204618
Skoffer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SELECT valcurs1.dt AS begindt,
nvl(MIN(valcurs2.dt), to_date('01.01.9999', 'dd.mm.yyyy')) AS
enddt,
valcurs1.val,
valcurs1.curs
FROM valcurs valcurs1 LEFT JOIN valcurs valcurs2 ON valcurs1.val = valcurs2.val
AND valcurs1.dt < valcurs2.dt
GROUP BY valcurs1.dt,
valcurs1.val,
valcurs1.curs

Вернет

01.01.11,"01.01.99","EUR","45"
01.01.11,"02.01.11","USD","35"
02.01.11,"04.01.11","USD","31"
04.01.11,"01.01.99","USD","30"

а джоин zatr'a с ним даст дубляжи из за перечения интервалов

01.01.11,"02.01.11","USD","35"
02.01.11,"04.01.11","USD","31"

Додумываем дальше)
...
Рейтинг: 0 / 0
SQL запрос - конвертация затрат в разных валютах в USD
    #37204630
Skoffer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
select zatr.date, zatr.val, zatr.summa, zatr.summa*T.curs as rubsumma
from zatr
left join
(select valcurs1.date as begindate, coalesce(min(valcurs2.date),дата_армагедона) as enddate, valcurs1.val, valcurs1.curs
from valcurs as valcurs1
left join valcurs as valcurs2
on valcurs1.val=valcurs2.val and valcurs1.date<valcurs2.date
group by valcurs1.date, valcurs1.val, valcurs1.curs) asT


on (zatr.date between T.begindate and T.enddate ) and (zatr.val=T.val)
заменить на on (zatr.date >= t.begindate and <t.enddate) and (zatr.val=T.val)
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / SQL запрос - конвертация затрат в разных валютах в USD
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]