Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.04.23;
Скачать: CL | DM;

Вниз

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

 
Nikolay M. ©   (2006-03-28 14:57) [0]

По мотивам ветки
http://delphimaster.net/view/15-1142073530/

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

1.
Есть таблица сотрудников: ID, Name, Age. Какой sql-запрос или
пакет запросов выдаст следующий набор данных. 3 столбца:
номер строки результата запроса, возраст (сортировка по убыванию),
кол-во человек данного возраста:

№ Age Count
1 60  1
2 55  2
........
9 20  14

2.
Таблица котировок содержит в себе тикер ценной бумаги, торговую
площадку, дату и значение котировки. Необходимо написать скрипт на
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)

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


 
Суслик ©   (2006-03-28 15:14) [1]

макс. вермя для второй задачи скажи.


 
Nikolay M. ©   (2006-03-28 15:19) [2]


> Суслик ©   (28.03.06 15:14) [1]
> макс. вермя для второй задачи скажи.


Дня 2-3 :)


 
Суслик ©   (2006-03-28 15:20) [3]

:)
выполнения, есно :)


 
Суслик ©   (2006-03-28 15:22) [4]

сам понимаешь, что задача несложная если не иметь ограничений по времени. Так что давай ограничения :)


 
Nikolay M. ©   (2006-03-28 15:24) [5]


> Суслик ©   (28.03.06 15:20) [3]

:)))

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


 
stone ©   (2006-03-28 15:33) [6]


> Nikolay M. ©


> RateDate       SMALLDATETIME,

Там просто дата или предполагает еще и время?


 
Nikolay M. ©   (2006-03-28 15:35) [7]


> Суслик ©   (28.03.06 15:22) [4]
> сам понимаешь, что задача несложная если не иметь ограничений
> по времени. Так что давай ограничения :)


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

SELECT FROM SELECT или
SELECT FROM table JOIN (SELECT FROM) или
SELECT FROM #tRate r1 JOIN #tRate r2 ON (r1.RateDate <= r2.RateDate).

Так что о каком быстродействии тут может идти речь :(


 
stone ©   (2006-03-28 15:36) [8]

Возможна ли ситуция когда на одну дату есть котировка на один тикер, а на другой нет? Или только: или есть на оба или на оба нет?


 
Курдль ©   (2006-03-28 15:37) [9]


> Nikolay M. ©   (28.03.06 14:57)


А кто такой "тикер ценной бумаги"?


 
Nikolay M. ©   (2006-03-28 15:38) [10]


> stone ©   (28.03.06 15:33) [6]
> Там просто дата или предполагает еще и время?


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


 
stone ©   (2006-03-28 15:45) [11]


> Курдль ©   (28.03.06 15:37) [9]
>
> > Nikolay M. ©   (28.03.06 14:57)
>
>
> А кто такой "тикер ценной бумаги"?

Фиг его знает, я так понял, что это EESR и LKOH


 
jack128 ©   (2006-03-28 15:57) [12]

Курдль ©   (28.03.06 15:37) [9]
А кто такой "тикер ценной бумаги"?

Тикер - краткое наименование ценной бумаги, используемый на бирже

Nikolay M. ©   (28.03.06 14:57)
1.
Есть таблица сотрудников: ID, Name, Age. Какой sql-запрос или
пакет запросов выдаст следующий набор данных. 3 столбца:
номер строки результата запроса, возраст (сортировка по убыванию),
кол-во человек данного возраста:

А если студент скажет, что формировать номер строки на сервере - это не много бредово (о ХП молчим) - такой ответ прокатит?? :)))


 
Nikolay M. ©   (2006-03-28 15:59) [13]


> А кто такой "тикер ценной бумаги"?


Сори, запостил тот вариант, в котором нет объяснения того, что такое тикер.
По сути - краткое название ценной бумаги. EESR и LKOH - соответственно акции РАО ЕЭС и ЛУкойл.


 
Nikolay M. ©   (2006-03-28 16:02) [14]


> А если студент скажет, что формировать номер строки на сервере
> - это не много бредово (о ХП молчим) - такой ответ прокатит?
> ? :)))


Нет, не прокатит.
Во-первых, номер строки не обязательно формировать в ХП, это можно сделать и одним запросом.
Во-вторых, не вижу в этом никакой бредовости. Если бы это действительно было бредом, для этого не создавался раздел ФАК-а с 5 или 6 вариантами решения.


 
Sergey13 ©   (2006-03-28 16:03) [15]

2[7] Nikolay M. ©   (28.03.06 15:35)
> Почти во всех решениях встречались
>SELECT FROM SELECT или
>...
>Так что о каком быстродействии тут может идти речь :(

А что "SELECT FROM SELECT" и быстродействие несовместимы? Не знал.


 
Bless ©   (2006-03-28 16:10) [16]


>  Если на одну дату существует
> более одной котировки, приоритетной считается котировка
> с площадки
> "MMVB".


А что означает "приоритетной"? Выводить только эту котировку?
А если с площадки MMVB котировок нет, а есть с нескольких других площадок, то что выводить?


 
jack128 ©   (2006-03-28 16:12) [17]

Nikolay M. ©   (28.03.06 16:02) [14]
это можно сделать и одним запросом.

Я знаю, джойном.  Но имхо, это не сопостовимые по сложности задачи по сравнению с формированием на клиенте..

Nikolay M. ©   (28.03.06 16:02) [14]
Если бы это действительно было бредом, для этого не создавался раздел ФАК-а с 5 или 6 вариантами решения.

Этот фак видимо создавался для тех кхм.. не скажу кого, кто не умеет в dbgrid"е отображать данные, отличные, от тех, что выдает запрос и не знающих, что такое вычисляемые поля DataSet"а..


 
jack128 ©   (2006-03-28 16:14) [18]

jack128 ©   (28.03.06 16:12) [17]
по сложности задачи

в смысле посложности для компьютера, по быстроджействию. Сложности для программиста не то ни ддругое не представляет, конечно. Да и не программист copy|paste"ом умеет пользоваться..


 
calm ©   (2006-03-28 16:14) [19]


> А кто такой "тикер ценной бумаги"?
>


В этом вся суть теста. Это был замаскированный тест на знание предметной области :)))


 
Суслик ©   (2006-03-28 16:16) [20]

будет время, напишу.
я не силен в быстром sql, но писать иногда приходится "тяжелые" запросы. Может и получится.


 
pasha_golub ©   (2006-03-28 16:36) [21]

А какайя СУБД?


 
Суслик ©   (2006-03-28 16:37) [22]


>  [21] pasha_golub ©   (28.03.06 16:36)

mssqlserver


 
Nikolay M. ©   (2006-03-28 16:40) [23]


> jack128 ©   (28.03.06 16:12) [17]
> Я знаю, джойном.  Но имхо, это не сопостовимые по сложности
> задачи по сравнению с формированием на клиенте..


Можно несколькими способами. В любом случае я лично не вижу смысла выносить расчет номера записи на клиента.


 
DiamondShark ©   (2006-03-28 16:41) [24]


> Почти во всех решениях встречались
>
> SELECT FROM SELECT или
> SELECT FROM table JOIN (SELECT FROM) или
> SELECT FROM #tRate r1 JOIN #tRate r2 ON (r1.RateDate <=
> r2.RateDate).
>
> Так что о каком быстродействии тут может идти речь :(

И вы ещё отбором кандидатов занимаетесь?


 
Nikolay M. ©   (2006-03-28 16:42) [25]


> А что "SELECT FROM SELECT" и быстродействие несовместимы?
>  Не знал.


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


 
DiamondShark ©   (2006-03-28 16:43) [26]


> В любом случае я лично не вижу смысла выносить расчет номера
> записи на клиента.

Тяжёлый случай.
Поменяйтесь местами с каким-нибудь из своих претендентов.


 
Nikolay M. ©   (2006-03-28 16:43) [27]


> DiamondShark ©   (28.03.06 16:41) [24]
> И вы ещё отбором кандидатов занимаетесь?


Уже нет. Сотрудник найден, надеюсь, что не придется через некоторое время придумывать новую задачу - эта уже засветилась :)


 
Nikolay M. ©   (2006-03-28 16:44) [28]


> Тяжёлый случай.
> Поменяйтесь местами с каким-нибудь из своих претендентов.


???
Не понял сакрального смысла.


 
Sandman25 ©   (2006-03-28 16:46) [29]

Nikolay M. ©   (28.03.06 16:44) [28]

Сервер не должен делать то, что может делать клиент. Рисовать кнопки или генерировать номера строк НД, например.


 
Sergey13 ©   (2006-03-28 16:46) [30]

2[25] Nikolay M. ©   (28.03.06 16:42)
> Если внутренний селект возвращает несколько сотен тысяч записей, а из них потом происходит выборка по условию, будет скан всего внутреннего НД.

Если вся таблица содержит миллионы записей, то скан сотен тысяч кажется уже не таким плохим. Все зависит от конкретики, а не от конструкции запроса. ИМХО.


 
Nikolay M. ©   (2006-03-28 16:46) [31]


> Bless ©   (28.03.06 16:10) [16]
> А что означает "приоритетной"? Выводить только эту котировку?
>
> А если с площадки MMVB котировок нет, а есть с нескольких
> других площадок, то что выводить?


Если на дату есть ММВБ и что-то еще, выводится котировка ММВБ.
Если на дату ММВБ отсутствует, но есть РТС, выводится котировка РТС.


 
jack128 ©   (2006-03-28 16:48) [32]

Nikolay M. ©   (28.03.06 16:44) [28]
Дима высказал вот эту мысль
jack128 ©   (28.03.06 15:57) [12]
что формировать номер строки на сервере - это не много бредово

но в своем фирменном, добродушном стиле ;-)


 
Nikolay M. ©   (2006-03-28 16:49) [33]


> Сервер не должен делать то, что может делать клиент. Рисовать
> кнопки или генерировать номера строк НД, например.


Даже спорить не буду. Пусть это останется истиной в последней инстанции.


 
Nikolay M. ©   (2006-03-28 16:49) [34]


> jack128 ©   (28.03.06 16:48) [32]
> Дима высказал вот эту мысль


См. [33].


 
Sandman25 ©   (2006-03-28 16:54) [35]

Nikolay M. ©   (28.03.06 16:49) [33]

Пусть это останется истиной в последней инстанции.

Не истиной. В остальном можно и не спорить, конечно.


 
stone ©   (2006-03-28 16:55) [36]

У меня получился такой результат:
EESR NULL 2005-12-29 00:00:00 NULL
EESR MMVB 2005-12-30 00:00:00 1.0
EESR NULL 2005-12-31 00:00:00 1.0
EESR NULL 2006-01-01 00:00:00 1.0
EESR RTS 2006-01-02 00:00:00 5.0
EESR MMVB 2006-01-03 00:00:00 2.0
EESR NULL 2006-01-04 00:00:00 2.0
EESR NULL 2006-01-05 00:00:00 2.0
EESR NULL 2006-01-06 00:00:00 2.0
EESR NULL 2006-01-07 00:00:00 2.0
EESR NULL 2006-01-08 00:00:00 2.0
EESR NULL 2006-01-09 00:00:00 2.0
EESR NULL 2006-01-10 00:00:00 2.0
LKOH NULL 2005-12-29 00:00:00 NULL
LKOH NULL 2005-12-30 00:00:00 NULL
LKOH NULL 2005-12-31 00:00:00 NULL
LKOH RTS 2006-01-01 00:00:00 8.0
LKOH MMVB 2006-01-02 00:00:00 3.0
LKOH NULL 2006-01-03 00:00:00 3.0
LKOH MMVB 2006-01-04 00:00:00 4.0
LKOH NULL 2006-01-05 00:00:00 4.0
LKOH NULL 2006-01-06 00:00:00 4.0
LKOH RTS 2006-01-07 00:00:00 9.0
LKOH NULL 2006-01-08 00:00:00 9.0
LKOH MMVB 2006-01-09 00:00:00 10.0
LKOH NULL 2006-01-10 00:00:00 10.0


 
DiamondShark ©   (2006-03-28 16:56) [37]

Хм... Действительно, извините за стиль...
Я просто устал воевать с ветеранами фокса, несущими свой богатый опыт в к-с среду.
Чесслово, номер записи -- это ещё самое невинное.
:(


 
stone ©   (2006-03-28 16:57) [38]

Решение с коментами сюда постить или как?


 
Paul_K ©   (2006-03-28 17:04) [39]


> Nikolay M. ©   (28.03.06 16:02) [14]
>
> > А если студент скажет, что формировать номер строки на
> сервере
> > - это не много бредово (о ХП молчим) - такой ответ прокатит?
>
> > ? :)))
>
>
> Нет, не прокатит.

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


> Если на дату есть ММВБ и что-то еще, выводится котировка
> ММВБ.
> Если на дату ММВБ отсутствует, но есть РТС, выводится котировка
> РТС.

одна маленькая разница. <Тикер на ММВБ> != <Тикер на РТС>
или я опять отстал от жизни?
опять же котировка имеет смысл только в паре с площадкой. Не так ли?


 
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

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


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

мдя.. слона я не заметил...
надо так ограничение по датам написать было
and tx.RateDate < dateadd(dd,1,@rep_date)

Но присмотрелся к условию
нашел ещё багов:)
у меня оказывается ещё и только ММВБ котировки вылезут к какому-то моменту гы:)
Кстати отсюда вопрос по условию
на дату 2006-01-08 имеем
4 LKOH MMVB 2006-01-04 00:00:00 4.0
9 LKOH RTS 2006-01-07 00:00:00 9.0
что должно быть в ответе? ммвб?  ртс?


 
stone ©   (2006-03-29 13:19) [82]


> что должно быть в ответе? ммвб?  ртс?


> Если котировка на дату Т отсутствует, берется котировка
> с максимальной датой, не превышающей Т.

Значит 8-го будет РТС, а уже 9-го "LKOH", "MMVB", "2006-01-09", 10
Думаю так, но лучше уточнить у Nikolay M. ©


 
Paul_K ©   (2006-03-29 14:52) [83]

хмм.. не совсем так вроде
я уже понял
7-го, 8-го и далее - РТС пока ММВБ не появится.. от так..


 
Paul_K ©   (2006-03-29 15:18) [84]

от так вроде верно....
begin tran
declare @start_date DATETIME,
       @end_date DATETIME,
       @rep_date DATETIME,
       @rate_place varchar(255),
@stock_name  varchar(255),  
@rate_value  Float

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

insert into #report (date_r,stock_name,rate_place,rate_value)
select distinct  @rep_date,SecurityTicker,null,null
from #tRate
set @rep_date = dateadd(dd,1,@rep_date)
end
declare bla cursor for select date_r,stock_name from #report
open bla
fetch bla into @rep_date,@stock_name
while @@fetch_status=0
begin
     select @rate_place=null, @rate_value=null
      if exists (select 1 from #tRate where RateDate=@rep_date and SecurityTicker=@stock_name having count(*)>1)
       select @rate_place=TradeSystem, @rate_value=Course
         from #tRate
        where RateDate = @rep_date
                 and SecurityTicker=@stock_name
                 and  TradeSystem="MMVB"
      else    
 select top 1 @rate_place=TradeSystem, @rate_value=Course
          from #tRate
                where SecurityTicker=@stock_name
                  and RateDate <= @rep_date
                  and RateDate >= @start_date
         order by RateDate desc
      --select @rep_date,@rate_place,@rate_value,@stock_name
      update  #report
         set  rate_place=@rate_place,
              rate_value=@rate_value
       where  date_r=@rep_date
         and  stock_name=@stock_name
fetch bla into @rep_date,@stock_name
end
close bla

deallocate  bla

commit tran

select convert(varchar,date_r,3),stock_name,rate_place,rate_value   from #report
order by stock_name,date_r

drop table #report

select * from #tRate order by RateDate
drop table #tRate

rep_date                       stock_name rate_place rate_value                                            
------------------------------ ---------- ---------- -----------------------------------------------------
29/12/05                       EESR       NULL       NULL
30/12/05                       EESR       MMVB       1.0
31/12/05                       EESR       MMVB       1.0
01/01/06                       EESR       MMVB       1.0
02/01/06                       EESR       RTS        5.0
03/01/06                       EESR       MMVB       2.0
04/01/06                       EESR       MMVB       2.0
05/01/06                       EESR       MMVB       2.0
06/01/06                       EESR       MMVB       2.0
07/01/06                       EESR       MMVB       2.0
08/01/06                       EESR       MMVB       2.0
09/01/06                       EESR       MMVB       2.0
10/01/06                       EESR       MMVB       2.0
29/12/05                       LKOH       NULL       NULL
30/12/05                       LKOH       NULL       NULL
31/12/05                       LKOH       NULL       NULL
01/01/06                       LKOH       RTS        8.0
02/01/06                       LKOH       MMVB       3.0
03/01/06                       LKOH       MMVB       3.0
04/01/06                       LKOH       MMVB       4.0
05/01/06                       LKOH       MMVB       4.0
06/01/06                       LKOH       MMVB       4.0
07/01/06                       LKOH       RTS        9.0
08/01/06                       LKOH       RTS        9.0
09/01/06                       LKOH       MMVB       10.0
10/01/06                       LKOH       MMVB       10.0


 
Nikolay M. ©   (2006-03-29 15:21) [85]

Виноват, прошу прощения, по работе отвлекали :)
Отвечаю.


> Кстати отсюда вопрос по условию
> на дату 2006-01-08 имеем
> 4 LKOH MMVB 2006-01-04 00:00:00 4.0
> 9 LKOH RTS 2006-01-07 00:00:00 9.0
> что должно быть в ответе? ммвб?  ртс?


На 2006-01-08 будет РТС-ная котировка, значение 9.


 
Paul_K ©   (2006-03-29 15:24) [86]

да у меня уже прошел приступ тупизма:)
проверь кстати тормознутое мое последнее решение. Опять я налажал ?


 
Nikolay M. ©   (2006-03-29 15:27) [87]


> Paul_K ©   (29.03.06 15:18) [84]


Да, такой вариант совпадает с stone ©   (28.03.06 16:55) [36], а у него, если я ничего не упустил, все правильно.

А ты всегда так курсоры обзываешь? :)


 
Paul_K ©   (2006-03-29 15:34) [88]

нет только когда они меня достают?)
а вот вопрос следующий. Быстродействие я не того не анализировал. встает вопрос какой вариантов быстрее и почему?
есть подозрение что мой медленнее. из-за курсора ..


 
Nikolay M. ©   (2006-03-29 15:48) [89]


> Быстродействие я не того не анализировал. встает вопрос
> какой вариантов быстрее и почему?


Я сейчас загружен по самые ушки, надеюсь, в вых напишу свой вариант, набросаю скрипт для заполнения таблицы котировок и сравню твой вариант, stone и свой (если он будет). Результаты и скрипт для прогона теста выложу.
Твой курсор, да еще в транзакции, скорее всего будет не самым быстрым - под транзакцию тоже ресурсы требуются.


 
Paul_K ©   (2006-03-29 15:56) [90]

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



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

Текущий архив: 2006.04.23;
Скачать: CL | DM;

Наверх




Память: 0.76 MB
Время: 0.045 c
15-1144165279
Бугага
2006-04-04 19:41
2006.04.23
Автоматизация идет полным ходом :)


15-1143903796
Knight
2006-04-01 19:03
2006.04.23
Слышал, что delphimaster продаётся?


2-1144566772
hgd
2006-04-09 11:12
2006.04.23
Graphics 32


1-1142567293
tigra
2006-03-17 06:48
2006.04.23
Работа с реестром


15-1144273946
Yegorchic
2006-04-06 01:52
2006.04.23
Файл и папка