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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.75 MB
Время: 0.013 c
5-1129901352
Vladix
2005-10-21 17:29
2006.04.23
Установка свойства DataSource для DB-Aware компонента


15-1144225435
ocean
2006-04-05 12:23
2006.04.23
Перезагрузить ADSL-модем


15-1143902843
Некто
2006-04-01 18:47
2006.04.23
Знатокам CSS, HTML и JavaScript


15-1143543460
Nikolay M.
2006-03-28 14:57
2006.04.23
Обещал разместить здесь предсобеседовательную задачку


8-1132228825
CondAL
2005-11-17 15:00
2006.04.23
проиграть события в midi файлах





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский