Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2006.04.23;
Скачать: [xml.tar.bz2];

Вниз

Обещал разместить здесь предсобеседовательную задачку   Найти похожие ветки 

 
Nikolay M. ©   (2006-03-28 17:05) [40]


> stone ©   (28.03.06 16:55) [36]
> У меня получился такой результат:
> EESR NULL 2006-01-04 00:00:00 2.0
> EESR NULL 2006-01-05 00:00:00 2.0


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


 
stone ©   (2006-03-28 17:07) [41]


> только было бы нелишним вместо NULL указать площадку

ну это не вопрос


> Решение, конечно, было бы интересно посмотреть.

а куда ложить-то?


 
LexxX ©   (2006-03-28 17:10) [42]

stone ©   (28.03.06 17:07) [41]
Выкладывай тут, припарировать будем! :)


 
Nikolay M. ©   (2006-03-28 17:12) [43]


> Николай, я не понял одного. Неужели у вас эти номера в реальности
> в запросе формируются при построении отчетов?
> это же замедляет запрос!!!!


Во-первых, мы вроде на ты.
Во-вторых, у меня ни в одном отчете нет номеров строк, но если будет нужно, я создам результирующую временную табличку с IDENTITY - это не сильно замедлит отчет/запрос.
В-третьих, тикеры, конечно, различаются. Котировки на различных площадках сравнивать (конечно) бессмысленно. Но не описывать же мне здесь еще и структуру таблицы ЦБ, площадок и тд? Это усложнило бы задачу настолько, что кто-то просто не стал бы ее решать.


 
stone ©   (2006-03-28 17:12) [44]

CREATE TABLE #t (
SecurityTicker VARCHAR (255),
TradeSystem    VARCHAR (255),
RateDate       SMALLDATETIME,
Course         FLOAT)

while  @StartDate <= @FinishDate
begin
INSERT INTO #T
SELECT "EESR", NULL, @StartDate, NULL
UNION ALL
SELECT "LKOH", NULL, @StartDate, NULL

update #T set
 TradeSystem = r.TradeSystem,
 Course = isnull(r.Course, t.Course)
from #T t
 left join #tRate r on t.RateDate = r.RateDate and t.SecurityTicker = r.SecurityTicker
where r.TradeSystem = "MMVB" and t.RateDate = @StartDate

update #T set
 TradeSystem = r.TradeSystem,
 Course = isnull(r.Course, t.Course)
from #T t
 left join #tRate r on t.RateDate = r.RateDate and t.SecurityTicker = r.SecurityTicker
where r.Course is not null and t.Course is null and t.RateDate = @StartDate
update #T set
 TradeSystem = (select top 1 TradeSystem from #T where RateDate < @StartDate and SecurityTicker = t.SecurityTicker order by RateDate desc),
 Course = (select top 1 Course from #T where RateDate < @StartDate and SecurityTicker = t.SecurityTicker order by RateDate desc)
from #T t
where t.RateDate = @StartDate and t.Course is null

select @StartDate = @StartDate + 1
end

select * from #t order by SecurityTicker, RateDate


для #tRate нужен индекс по RateDate
по SecurityTicker в зависимости от количества этих самых тикеров


 
Nikolay M. ©   (2006-03-28 17:14) [45]


> stone ©   (28.03.06 17:07) [41]
> а куда ложить-то?


А что, текст скрипта больше нескольких килобайт? Если нет, то текст в форум и выкладывай :)


 
stone ©   (2006-03-28 17:14) [46]

последний UPDATE можно соптимизировать, но это имеет смысл при большом количестве тикеров и периоде отчета


 
LexxX ©   (2006-03-28 17:25) [47]

stone ©   (28.03.06 17:12) [44]

Не select @StartDate = @StartDate + 1 ,
а set @StartDate = @StartDate + 1


 
stone ©   (2006-03-28 17:26) [48]


> LexxX ©   (28.03.06 17:25) [47]

а какая разница?


 
Nikolay M. ©   (2006-03-28 17:27) [49]


> Не select @StartDate = @StartDate + 1 ,
> а set @StartDate = @StartDate + 1


Почему?


 
LexxX ©   (2006-03-28 17:28) [50]

stone ©   (28.03.06 17:26) [48]
а какая разница?


Правильно, согласно T-SQL, SET использовать.


 
Курдль ©   (2006-03-28 17:29) [51]


> Nikolay M. ©   (28.03.06 15:38) [10]
> Здесь, для упрощения, только дата. В жизни есть еще и время.

Интересно знать, это в какой жизни ценные бумаги котируют чаще, чем раз в день? Кроме того, большинство площадок вообще не котируют свои инструменты, а сверяются по ценам (max покупки/min продажи) на момент закрытия, либо по последней сделке дня. Единственная официальная и совершенно четкая котировка есть у основных мировых валют, публикуемая ЦБ. Раньше (не знаю, как сейчас) все расчеты велись на основании бюллетеней РБК, и то по инструментам первого эшелона.


> Если есть время и желание, напиши скрипт, который будет
> генерить тысяч 100 записей, потом на одном компьютере можно
> будет разные варианты прогнать.

У меня есть такая база, правда не под MS SQL и без связи котировка-площадка.


 
LexxX ©   (2006-03-28 17:30) [52]

LexxX ©   (28.03.06 17:28) [50]

SET @local_variable
Sets the specified local variable, previously created with the DECLARE @local_variable statement, to the given value.

Syntax
SET { { @local_variable = expression }
       | { @cursor_variable = { @cursor_variable | cursor_name
               | { CURSOR [ FORWARD_ONLY | SCROLL ]
                   [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
                   [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
                   [ TYPE_WARNING ]
               FOR select_statement
                   [ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] }
                   ]
               }
       } }
   }



 
stone ©   (2006-03-28 17:33) [53]


> LexxX ©   (28.03.06 17:30) [52]

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


 
Nikolay M. ©   (2006-03-28 17:34) [54]


> LexxX ©


Аргумент так и не был приведен...


 
LexxX ©   (2006-03-28 17:37) [55]

stone ©   (28.03.06 17:33) [53]
Set годится только для присвоения значения одной переменной, select в это плане более универсальный

Я не спорю что селектом нельзя присваивать переменным значения, просто SQL Server Books Online говорит следующее:
It is recommended that SET @local_variable be used for variable assignment rather than SELECT @local_variable. For more information, see SET @local_variable.


 
LexxX ©   (2006-03-28 17:37) [56]

Nikolay M. ©   (28.03.06 17:34) [54]
Аргумент так и не был приведен...


см. [55]


 
LexxX ©   (2006-03-28 17:40) [57]

stone ©   (28.03.06 17:33) [53]
Set годится только для присвоения значения одной переменной, select в это плане более универсальный


Ни кто не запрещает использовать следующую конструкцию:
SET @local_variable1 = expression1,
   @local_variable2 = expression2,
   ....
   @local_variableN = expressionN


 
Nikolay M. ©   (2006-03-28 17:42) [58]


> Курдль ©   (28.03.06 17:29) [51]
> Интересно знать, это в какой жизни ценные бумаги котируют
> чаще, чем раз в день?


В моей, например (жизни). Никогда не приходилось иметь дело с котировками онлайн, которые льются из шлюзов торговых систем для моментального расчета стоимостей портфелей, средневзвесов, профит-лосей?


 
Курдль ©   (2006-03-28 17:49) [59]


> Никогда не приходилось иметь дело с котировками онлайн,
> которые льются из шлюзов торговых систем...

Не приходилось.
Очередь заявок - да, цены сделок - да, котировки - нет :(
А можно ссылочку на какой-нить ресурс одной из площадок, поставляющей такие данные? (Отстал я от жизни-и-и...)


 
Sandman25 ©   (2006-03-28 17:51) [60]

ИМХО MSSQL разлагает программистов. Этак они и в Informix вместо
LET i = 1 будут писать SELECT 1 INTO i FROM systables WHERE id=1 и еще спорить о правильном способе :)


 
stone ©   (2006-03-28 17:51) [61]


> LexxX ©   (28.03.06 17:40) [57]
> Ни кто не запрещает использовать следующую конструкцию:
> SET @local_variable1 = expression1,
>    @local_variable2 = expression2,
>    ....
>    @local_variableN = expressionN

Серьезно?
declare @a int, @b int
set @a = 1, @b = 2

Server: Msg 170, Level 15, State 1, Line 2
Line 2: Incorrect syntax near ",".


 
DiamondShark ©   (2006-03-28 17:59) [62]


> Set годится только для присвоения значения одной переменной,
>  select в это плане более универсальный

только у select ещё побочный эффект есть.


 
calm ©   (2006-03-28 18:04) [63]


> только у select ещё побочный эффект есть.

нукась?


 
Nikolay M. ©   (2006-03-28 18:09) [64]


> Курдль ©   (28.03.06 17:49) [59]
> Не приходилось.
> А можно ссылочку на какой-нить ресурс одной из площадок


Счастливый человек :)))

ММВБ, РТС.
Пару лет назад у РТС, кажется, был платный шлюз, куда можно было по DDE (устаревшая такая абревиатура :) ) чуть ли не екселем ходить.
У нас сейчас это делается централизованно, так что в деталях рассказать, к сожалению, не смогу, я в этом вопросе являюсь только потребителем информации :)


 
DiamondShark ©   (2006-03-28 18:12) [65]


> calm ©   (28.03.06 18:04) [63]

изменение @@ROWCOUNT и генерация сообщения клиенту (если не включён nocount).


 
LexxX ©   (2006-03-28 18:35) [66]

stone ©   (28.03.06 17:51) [61]

:-/ Пардон, однако...
Не проверив запостил :((


 
Карелин Артем ©   (2006-03-28 19:26) [67]


> Nikolay M. ©   (28.03.06 14:57)  


> расстановка индексов -
> на усмотрение исполнителя.

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


 
Nikolay M. ©   (2006-03-28 20:39) [68]


> Карелин Артем ©   (28.03.06 19:26) [67]
> А вот это, извините, на мой взгляд не должно быть на совести
> исполнителя в данном случае.


Как раз в данном случае (задача до собеседования) - это только на совести исполнителя. Если бы кто-то заикнулся, что индексы пусть расставляет оптимизатор, то собеседования с ним даже не состоялось бы :)


 
Карелин Артем ©   (2006-03-28 20:57) [69]


> Nikolay M. ©   (28.03.06 20:39) [68]

Задача стоит добиться МАКСИМАЛЬНОГО быстродействия и по моему нескромному имху этого следует добиваться совместно с железкой :)))
Хотя сложно конечно быть экзаменатором - приходится немного отрываться от привычных практических тропинок в сторону академизма (знаю - плавал)...


 
Nikolay M. ©   (2006-03-28 22:10) [70]


> Карелин Артем ©   (28.03.06 20:57) [69]
> Задача стоит добиться МАКСИМАЛЬНОГО быстродействия и по
> моему нескромному имху этого следует добиваться совместно
> с железкой :)))


Предлагаешь каждому кандидату попробовать себя в качестве DBA? Массивы поднять, файлы по дискам разнести, патчи накатить, маршрутизацию настроить? :)


 
Карелин Артем ©   (2006-03-29 06:10) [71]


> Nikolay M. ©   (28.03.06 22:10) [70]

Ну зачем так глобально :)))
Я про то, что железка лучше сама подскажет как лучше забубенить например индексы.


 
Paul_K ©   (2006-03-29 08:44) [72]

посмотрел. да, задачка то быстрокрылая не получается.. особенно на "милионниках". и в один запрос не решается.
если не до конца соблюдать  условия то следующее решение и ответ
/*Таблица котировок содержит в себе тикер ценной бумаги, торговую
площадку, дату и значение котировки. Необходимо написать скрипт на
T-SQL, который возвращает значение котировки для ценных бумаг EESR и LKOH,
тикер, название торговой площадки и дату котировки на каждую дату между
@StartDate и @FinishDate включительно. Если на одну дату существует
более одной котировки, приоритетной считается котировка с площадки
"MMVB". Если котировка на дату Т отсутствует, берется котировка с
максимальной датой, не превышающей Т. Если котировка за предыдущие дни
отсутствует, котировка не выдается. Предполагается, что таблица
котировок содержит в себе более миллиона записей, поэтому скрипт
должен быть оптимальным по скорости выполнения, расстановка индексов -
на усмотрение исполнителя.
*/
DECLARE
@StartDate  SMALLDATETIME,
@FinishDate SMALLDATETIME

SELECT
@StartDate  = "2005-12-29",
@FinishDate = "2006-01-10"

IF (OBJECT_ID ("tempdb..#tRate") IS NOT NULL)
DROP TABLE #tRate

CREATE TABLE #tRate (
RateID         INT IDENTITY (1, 1),
SecurityTicker VARCHAR (255),
TradeSystem    VARCHAR (255),
RateDate       SMALLDATETIME,
Course         FLOAT)

create table #report(
date_r datetime,
stock_name VARCHAR (255),
rate_place VARCHAR (255),
rate_value FLOAT
)
INSERT INTO #tRate
(SecurityTicker, TradeSystem, RateDate, Course)
SELECT
"EESR", "MMVB", "2005-12-30", 1
UNION ALL
SELECT
"EESR", "MMVB", "2006-01-03", 2
UNION ALL
SELECT
"LKOH", "MMVB", "2006-01-02", 3
UNION ALL
SELECT
"LKOH", "MMVB", "2006-01-04", 4
UNION ALL
SELECT
"EESR", "RTS", "2006-01-02", 5
UNION ALL
SELECT
"EESR", "RTS", "2006-01-03", 6
UNION ALL
SELECT
"LKOH", "RTS", "2006-01-04", 7
UNION ALL
SELECT
"LKOH", "RTS", "2006-01-01", 8
UNION ALL
SELECT
"LKOH", "RTS", "2006-01-07", 9
UNION ALL
SELECT
"LKOH", "MMVB", "2006-01-09", 10

begin tran
declare @start_date DATETIME,
       @end_date DATETIME,
       @rep_date DATETIME,
       @rate_place varchar(255)    

set @start_date =convert(datetime,isnull(convert(varchar,@StartDate,3),"0/0/1900"),3)
set @end_date = convert(datetime,isnull(convert(varchar,dateadd(dd,1,@FinishDate),3),"0/0/1900"),3)
set @rep_date=@start_date
while @rep_date<@end_date
begin
  set @rate_place = "MMVB" -- или первая из курсора по площаткам отсортированного по убыванию приоритета для отчета
   insert into #report (date_r,stock_name,rate_place,rate_value)
select distinct @rep_date,
       tr.SecurityTicker,
       tr.TradeSystem,
       (select t.Course
               from  #tRate as t
              where t.SecurityTicker = tr.SecurityTicker
                       and t.TradeSystem = tr.TradeSystem
                and t.RateDate = (select max(tx.RateDate)
                              from  #tRate as tx
                               where tx.SecurityTicker = t.SecurityTicker
                                 and tx.TradeSystem = t.TradeSystem
                                 and tx.RateDate > @start_date
     and tx.RateDate < @rep_date
                             )
  )
from #tRate as tr
where upper(tr.TradeSystem) =@rate_place
-- а вот тут надо бы зациклить по оставшимся площадкам и нижеследующему exist
  set @rate_place = "RTS"
 
  if exists (select 1 from #report where date_r=@rep_date and rate_value is null )
      update #report
         set rate_place=@rate_place,
             rate_value = (select t.Course
                      from  #tRate as t
                     where t.TradeSystem =@rate_place
                              and t.SecurityTicker =stock_name
                              and t.RateDate = (select max(tx.RateDate)
                             from  #tRate as tx
                   where tx.SecurityTicker = t.SecurityTicker
                       and tx.TradeSystem = t.TradeSystem
                                 and tx.RateDate > @start_date
            and tx.RateDate < @rep_date
                              )
  )
where  date_r=@rep_date
        and rate_value is null
set @rep_date = dateadd(dd,1,@rep_date)
end
commit tran
select convert(varchar,date_r,3),stock_name,rate_place,rate_value   from #report
order by date_r

drop table #tRate
drop table #report


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


 
Nikolay M. ©   (2006-03-29 10:38) [73]


> Paul_K ©   (29.03.06 08:44) [72]

Курсор в топку :)
А если еще вспомнить про купоны, амортизацию, номиналы у бондов и облигаций и процентную котировку, сплиты, то задача получается отнюдь для разминки мозгов, а для их закипания :)


 
Paul_K ©   (2006-03-29 10:50) [74]

в топку?
ну собрать бумаги на кажную дату из периода без цикла? а ещё вычесть выходные? и без цикла? (да слово "курсор" употребил зазря)

А потом без цикла скакать по неограниченному количеству прлощадок?

а так хочется, чтобы отчет одним запросом собирался:)


 
Nikolay M. ©   (2006-03-29 10:54) [75]


> Paul_K ©   (29.03.06 10:50) [74]
> в топку?


Угу. В 99% случаев, когда цикл необходим, можно обойтись без курсора.


> а так хочется, чтобы отчет одним запросом собирался:)


Практически нереально, ты же сам понимаешь :(


 
Bless ©   (2006-03-29 10:55) [76]


> Nikolay M. ©   (28.03.06 16:46) [31]
> > А если с площадки MMVB котировок нет, а есть с нескольких
>
> > других площадок, то что выводить?
>
>
> Если на дату есть ММВБ и что-то еще, выводится котировка
> ММВБ.
> Если на дату ММВБ отсутствует, но есть РТС, выводится котировка
> РТС.


А если нет ни ММВБ, ни РТС, а есть еще котировки с десятка других площадок, тоже выбрать какую-то одну? Или площадки строго ограничены только этими двумя?


 
Paul_K ©   (2006-03-29 11:03) [77]


> Угу. В 99% случаев, когда цикл необходим, можно обойтись
> без курсора.

Точно? ой сумневаюсь.
от скажем твоя же задача.
тока площадок многа, и лежать они в t_places (place_code varchar(30),place_name varchar(255), prior numeric(10,0))
place_code
MMWB
RTS
SPFB
FOREX
.....
.....
.....

и как без курсора по всем площадкам собрать?
как я понимаю нужно последовательно по каждой площадке апдейтить пока есть записи с null или есть площадки необработанные.
Можно не объявлять курсор, а собрать временную таблицу, брать первую запись, обрабатывать, удалять запись и по новой, пока табличка не кончится. Но это тот же курсор по сути


 
Nikolay M. ©   (2006-03-29 11:06) [78]


> Bless ©   (29.03.06 10:55) [76]


Площадки - только ММВБ и РТС, других нет.


 
Paul_K ©   (2006-03-29 11:09) [79]


> Nikolay M. ©   (29.03.06 10:38) [73]

а решение то верное?


 
stone ©   (2006-03-29 11:29) [80]


> Paul_K ©   (29.03.06 11:09) [79]
>
> а решение то верное?

было
INSERT INTO #tRate
(SecurityTicker, TradeSystem, RateDate, Course)
SELECT
"EESR", "MMVB", "2005-12-30", 1

в #report
30/12/05 EESR RTS NULL

дальше не смотрел



Страницы: 1 2 3 вся ветка

Форум: "Прочее";
Текущий архив: 2006.04.23;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.65 MB
Время: 0.017 c
2-1144402600
cautur
2006-04-07 13:36
2006.04.23
Разноцветный TLabel или TMemo


15-1143637602
Yegorchic
2006-03-29 17:06
2006.04.23
Программа для моделирования дворов


1-1142839820
tigra
2006-03-20 10:30
2006.04.23
Работа с принтером


8-1132494180
DDDiM
2005-11-20 16:43
2006.04.23
звуковой осцилограф


2-1144535831
iyshnik
2006-04-09 02:37
2006.04.23
Относительный путь





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский