Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Новости сайта "Упражнения по SQL" (http://www.sql-ex.ru) 214


Новости сайта "Упражнения по SQL (http://www.sql-ex.ru)"

Выпуск 214 от 01 ноября 2008 г.

Новым посетителям сайта

SQL Exercises Сайт посвящен изучению языка, с помощью которого осуществляется взаимодействие с реляционными (и не только) СУБД. Суть обучения состоит в выполнении заданий на написание запросов к учебным базам данных; при этом система контролирует правильность выполнения заданий. В настоящее время реализованы все операторы подъязыка манипуляции данными (DML), которые включают в себя оператор извлечения данных SELECT, а также операторы модификации данных - INSERT, DELETE и UPDATE.

Мы надеемся, что справочного материала сайта окажется достаточно для самостоятельного обучения. Кроме того, свои решения вы можете обсудить на форуме сайта. Опытных же специалистов приглашаем проверить (продемонстрировать) свое мастерство и принять участие в соревновании, обеспечиваемом рейтинговой системой учета времени выполнения заданий. Фактически, рейтинг ведется на втором этапе тестирования, который начинается сейчас после решения 51-й задачи первого этапа. При подсчете рейтинга каждого участника отбрасывается один самый худший показатель среди всех решенных им упражнений.

Демонстрация плана выполнения запроса и сравнительная оценка эффективности решений поможет вам освоить принципы оптимизации запросов, которые пригодятся на третьем рейтинговом этапе, который начинается после 138 задачи.

Имеется возможность получить сертификат по SQL DML при выполнении определенного количества заданий.


Новости сайта

§ Новыми данными от автора усилена проверка задачи 89.

§ В блоке новостей на главной странице сайта разместил картинку географии посетителей сайта. Статистика еще не накоплена, поэтому карта пока не отражает реального положения, которое я оцениваю по статистике LiveInternet.

§ Рекомендую почитать форум. На этой неделе опубликована масса классных решений многих задач, вызванная желанием orange перерешать все задачи перед 3 этапом. Приглашаю всех поучиться писать запросы у orange, anddros, @Nikotin - главных авторов постов прошедшей недели.

§ На этой неделе дважды сменился лидер. Незначительная разница в баллах обещает нам захватывающее соперничество между $erges и @Nikotin при появлении на 3 этапе новых задач. Одна уже скоро появится. Автор - @Nikotin. :-)
Жду "пробуждения" еще нескольких лидеров, которые должны вмешаться в спор на первые места. Изменения среди лидеров (решенные за неделю задачи третьего этапа):
1. $erges (148)
2. @Nikotin (148, 149)
9. lepton (145)
15. Ozzy (143)
40. mar_vi(139)

§ Одна задача до третьего этапа осталась:
47. MeVit (137, 32.250)

§ Новые лица в ТОР 100 и вернувшиеся туда:
100. Ashton (125, 23.022)

§ Продвинулись в рейтинге:
45. _Bkmz_ (137, 4.612)
58. ivan.korobov (134, 137.339)
69. denzel (132, 118.192)
85. lexaNRJ (127, 91.206)

§ Продвижение ближайших претендентов на попадание в ТОР 100:
146. FanOfBeer (118, 122.763)

§ На этой неделе сертифицированы:
Ashton (B08030894) [AR] - г.Москва, Россия

§ Число подписчиков - 3834

Число участников рейтинга - 19015

Число участников второго этапа - 1588

Число участников третьего этапа - 41

Сертифицировано на сайте - 335

Лучшие результаты (ТОР 20)

No Person Number of
Sel_ex
Last_Sel Number of
DML_ex
Scores Days Days_2 Days_3 S_3 LastSolved LastVisit
1 >Сальников С.А. ($erges) 149 148 21 360 248 3.183 3.688 36 31 Oct 2008 31 Oct 2008
2 Никотин В.М. (@Nikotin) 149 149 21 360 62 7.665 3.751 36 28 Oct 2008 31 Oct 2008
3 Печатнов В.В. (pvv) 149 149 21 360 357 30.865 17.490 36 10 Oct 2008 31 Oct 2008
4 Селезнёв А.С. (Артём С.) 148 149 21 357 322 38.520 29.235 36 25 Sep 2008 31 Oct 2008
5 Креславский О.М. (Arcan) 149 149 21 360 617 48.147 36.296 36 08 Oct 2008 31 Oct 2008
6 Карасёва Н.В. (vlksm) 149 149 21 360 866 77.240 49.173 36 18 Sep 2008 31 Oct 2008
7 Держальцев В.А. (MadVet) 140 146 21 341 1257 60.815 28.482 28 24 Sep 2008 06 Oct 2008
8 Любченко В.А. (IAS56) 139 146 21 340 615 403.439 373.617 28 11 May 2008 28 Oct 2008
9 Мурашкин И.В. (lepton) 144 54 21 346 950 43.615 33.116 26 28 Oct 2008 29 Oct 2008
10 Голубин Р.С. (Roman S. Golubin) 143 145 21 343 1122 93.054 58.822 25 13 Sep 2008 29 Oct 2008
11 Nikolaenko A.V. (Shadow77) 145 126 21 347 436 77.520 14.010 23 22 Oct 2008 24 Oct 2008
12 Солдатенков Ю.С. (SolYUtor) 141 146 21 339 819 22.703 6.102 20 14 Aug 2008 23 Oct 2008
13 Белогурова К. (Katy_Ekb) 135 143 21 328 361 10.714 4.673 18 20 May 2008 16 Oct 2008
14 Егоров А.Б. (ABEgorov) 140 144 21 337 180 12.917 8.815 18 03 Aug 2008 12 Aug 2008
15 Зотов П.Г. (Ozzy) 141 143 21 338 229 40.955 58.553 18 25 Oct 2008 31 Oct 2008
16 Войнов П.Е. (pаparome) 142 146 21 338 1125 3.132 .213 17 22 Sep 2008 07 Oct 2008
17 Дроздков А.Н. (anddros) 143 145 21 341 140 4.236 .921 17 14 Oct 2008 31 Oct 2008
18 iglbeat (iglbeat) 140 145 21 336 360 34.601 15.225 17 08 Aug 2008 25 Aug 2008
19 Северюхин Ю.А. (Venser) 131 142 21 319 335 4.925 .655 14 01 Feb 2008 04 Feb 2008
20 Борисенков Д.В. (xuser) 140 142 21 332 261 3.346 .926 14 18 Oct 2008 31 Oct 2008

Лучшие результаты за неделю

No surname n_sel sel_all sel_scores dml_scores scores rating last_visit
1 Муллаханов Р.Х. (rem) 55 68 110 34 144 558 30 Oct 2008
2 >Щудло Ф.М. (eksodus) 39 52 83 34 117 921 31 Oct 2008
3 >Махров А.А. (anticooler) 52 52 98 0 98 1653 31 Oct 2008
4 Naumkina (chocolate) 27 27 51 19 70 2888 31 Oct 2008
5 Фадеев (Cerebral) 20 50 39 30 69 1038 31 Oct 2008
6 >Yakovlev (naxa) 32 32 60 0 60 3594 31 Oct 2008
7 >Шиндин А.В. (AlShin) 28 67 48 11 59 589 31 Oct 2008
8 >Dubrovskaya I. (Iryna) 32 32 54 0 54 4110 31 Oct 2008
9 Васильева Н.А. (Рыжая Нина) 11 54 19 34 53 897 31 Oct 2008
10 >Соколов А.С. (WFR) 18 51 37 16 53 1219 31 Oct 2008
11 Sizyh M.N. (MarSi) 8 67 16 34 50 603 31 Oct 2008
12 >Уланова Л.В. (STARosta) 17 31 41 9 50 2075 30 Oct 2008
13 Клименко А.Н. (zprotos) 15 33 33 16 49 2356 30 Oct 2008
14 >Кузнецов А.Г. (Alexus) 27 27 49 0 49 4623 31 Oct 2008
15 Морозов (Troll) 27 27 49 0 49 4645 30 Oct 2008
16 >Чуринов Р.А. (Чуринов Роман) 24 24 45 0 45 5105 31 Oct 2008
17 Церетян Ю.Г. (Karasb) 16 38 40 0 40 2699 28 Oct 2008
18 >Kotov K.V. (jaloS) 15 29 38 0 38 3978 31 Oct 2008
19 >Демиденко В. (3ul) 21 22 38 0 38 5856 31 Oct 2008
20 Руппиев С. (GraySerg) 21 21 38 0 38 5891 30 Oct 2008
21 Двуреченский П. (Dvurechensky) 7 53 14 23 37 1104 28 Oct 2008
22 Демидов А.Б. (AlexandrB) 8 51 16 21 37 1163 31 Oct 2008
23 Шумихин М.В. (Макс82) 14 25 34 0 34 4989 29 Oct 2008
24 Бавтрук (_irina_) 2 47 3 30 33 1115 30 Oct 2008
25 >Санкевич (Don) 20 20 32 0 32 6640 31 Oct 2008
26 >Иванов С.В. (Skypppher) 19 19 31 0 31 6762 31 Oct 2008
27 >Иванов В.С. (AntXD) 21 21 31 0 31 6833 31 Oct 2008
28 Баранов Н.С. (Panasonic) 6 41 15 15 30 1269 31 Oct 2008
29 Назарова (L__) 12 12 13 17 30 7058 30 Oct 2008

Изучаем SQL

Требования к SQL Server по усилению поддержки: предложение OVER() и упорядоченные вычисления (продолжение, начало в вып.195-199, 202-213)

Itzik Ben-Gan и Sujata Mehta (оригинал: SQL Server Feature Enhancement Request - OVER Clause and Ordered Calculations )
Перевод: Карасева Н.В.

v. Ограничение окон (ROWS, RANGE)

Подчиненные предложения ROWS и RANGE предложения OVER применимы к некоторым аналитическим функциям - главным образом агрегатным, но также и другим, и они позволяют вам определить окно строк, на которых будет вычисляться функция.

ROWS позволяет определить окно относительно текущей строки, и полезно для вычислений со скользящим окном. Синтаксис для конструкции ROWS следующий:

ROWS BETWEEN <выражение_от> AND <выражение_до>

<выражение_от> может быть одним из:


        
  • <целочисленное_выражение> {PRECEDING | FOLLOWING}
  • UNBOUNDED PRECEDING
  • CURRENT ROW
  • <выражение_до> может быть одним из:

    
            
  • <целочисленное_выражение> {PRECEDING | FOLLOWING}
  • UNBOUNDED FOLLOWING
  • CURRENT ROW
  • <целочисленное_выражение> представляет смещение в терминах числа строк, находящихся перед (PRECEDING) или после (FOLLOWING) текущей строки. Другие варианты понятны без объяснений.

    Как пример для использования конструкции ROWS, рассмотрим таблицу EmpOrders, приведенную ранее. Предположим, что требуется вычислить агрегированные значения (суммарное и среднее значение qty) для работника (empid) за 2 месяца, предшествующих текущему месяцу, и текущий месяц. Без предложения OVER вы использовали бы или самосоединения, или подзапросы. Вот решение, использующее самосоединение:

    -- Скользящие агрегаты для служащего за три месяца перед текущим
    SELECT O1.empid,
      CONVERT(VARCHAR(7), O1.ordermonth, 121) AS tomonth, O1.qty AS qtythismonth,
      SUM(O2.qty) AS totalqty,
      AVG(1.*O2.qty) AS avgqty
    FROM dbo.EmpOrders AS O1
      JOIN dbo.EmpOrders AS O2
        ON O2.empid = O1.empid
        AND (O2.ordermonth > DATEADD(month, -3, O1.ordermonth)
             AND O2.ordermonth <=  O1.ordermonth)
    GROUP BY O1.empid, O1.ordermonth, O1.qty
    ORDER BY O1.empid, O1.ordermonth;
    

    Решение с предложением OVER могло бы выглядеть так:

    SELECT empid,
      CONVERT(VARCHAR(7), ordermonth, 121) AS tomonth, qty AS qtythismonth,
      SUM(qty) OVER(PARTITION BY empid
                 ORDER BY ordermonth
                 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS totalqty,
      AVG(1.*qty) OVER(PARTITION BY empid
                     ORDER BY ordermonth
                     ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS avgqty
    FROM dbo.EmpOrders
    ORDER BY empid, ordermonth;
    

    Видно, что последнее решение проще и интуитивно понятнее. Более того, в его оценку стоимости не входит join и отсутствует повторное многократное сканирование одних и тех же строк.

    Если предложение BETWEEN отсутствует и никакой верхний предел не определен, то предполагается CURRENT ROW (текущая строка) в качестве верхнего предела. Например, вместо ROWS BETWEEN 2 PRECEDING AND CURRENT ROW вы можете указать ROWS 2 PRECEDING. Если конструкция окна вообще отсутствует, то предполагается ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.

    Конструкция окна RANGE позволяет вам определить ранг, основанный на логическом смещении (в терминах упорядоченных значений) в отличие от ROWS, где вы определяете физическое смещение (в терминах числа строк). Логическое смещение основано на значении в столбце текущей строки, по которому выполняется сортировка, и оно может быть либо числом, либо датой. Важным элементом подчиненного предложения RANGE является возможность использования отсутствующей в SQL Server поддержки временных (datetime) интервалов. Конструкция RANGE оказывается полезной, когда число строк в окне может меняться. Например, предположим, что в таблице EmpOrders не гарантируется отсутствие пропусков в деятельности работника. Работник может работать в январе и марте, но не работать в феврале. Понятно, что в этом случае последнее представленное решение с использованием ROWS логически не эквивалентно решению с использованием самосоединения. Решение с ROWS определяет окно, основанное на количестве строк, вместо рассмотрения периода времени, который начался 2 месяца назад и заканчивается текущим месяцем. Конструкция RANGE с поддержкой интервалов разрешает эту проблему:

    SELECT empid,
      CONVERT(VARCHAR(7), ordermonth, 121) AS tomonth, qty AS qtythismonth,
      SUM(qty) OVER(PARTITION BY empid
                 ORDER BY ordermonth
                 RANGE BETWEEN INTERVAL '2' MONTH PRECEDING
                           AND CURRENT ROW) AS totalqty,
      AVG(1.*qty) OVER(PARTITION BY empid
                     ORDER BY ordermonth
                     RANGE BETWEEN INTERVAL '2' MONTH PRECEDING
                                 AND CURRENT ROW) AS avgqty
    FROM dbo.EmpOrders
    ORDER BY empid, ordermonth;
    

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

    SELECT empid,
      CONVERT(VARCHAR(7), ordermonth, 121) AS tomonth, qty AS qtythismonth,
      SUM(qty) OVER(PARTITION BY empid
                 ORDER BY YEAR(ordermonth) * 100 + MONTH(ordermonth)
                 RANGE BETWEEN 2 PRECEDING
                           AND CURRENT ROW) AS totalqty,
      AVG(1.*qty) OVER(PARTITION BY empid
                     ORDER BY YEAR(ordermonth) * 100 + MONTH(ordermonth)
                     RANGE BETWEEN 2 PRECEDING
                               AND CURRENT ROW) AS avgqty
    FROM dbo.EmpOrders
    ORDER BY empid, ordermonth;
    

    Здесь сортировка основана на целочисленном значении, полученном конкатенацией года и месяца (YEAR (ordermonth) * 100 + MONTH (ordermonth)). Например, июль 1996 представлен значением 199607. В виду того, что упорядочение идет по этим целочисленным значениям, выражение 2 PRECEDING представляет две единицы до текущего значения в порядке сортировки - другими словами, 2 месяца тому назад. Но снова, это добавляет сложность и ухудшает производительность. Заметим, что вы можете также ссылаться на выражение сортировки в выражениях границы конструкции RANGE. Например, предположим, что имеется выражение сортировки ORDER BY col1, тогда RANGE BETWEEN 2 PRECEDING эквивалентно ROWS BETWEEN (col1 - 2) PRECEDING. Однако некоторые выражения просто должны включать выражение сортировки, например, col1/2.

    Ввиду того, что конструкция RANGE основана на логическом смещении относительно значения сортировки в текущей строке, включение подчиненного предложения ORDER BY является обязательным и ограничивается одним выражением. Когда ключевое слово BETWEEN отсутствует и <выражение_до> не задано, по умолчанию этой границей окна является текущая строка (CURRENT ROW).

    Как вы уже поняли, конструкции ROWS и RANGE очень удобны для вычислений на скользящих окнах. Мы надеемся, что кроме расширения поддержки предложения OVER, Server SQL также введет поддержку интервалов, позволяющих получать простые, естественные и эффективные решения этих общих задач.

    (Продолжение следует...)

    Полезная информация

    § Приглашаем вас посетить новый проект - Интерактивный учебник по SQL.
       Ресурс позиционируется как "справочное обеспечение" для сайта SQL-EX.RU, но может использоваться и независимо от него.

    § Онлайновый выпуск рассылки можно почитать на сайте.

    § Все статьи, публикуемые в рассылке, затем выкладываются на сайте Книги и статьи по SQL.

    § Хотите поддержать проект? Вот инструкция по применению. :-)

    Контакты

    По всем вопросам, связанным с функционированием сайта, проблемами при решении упражнений, идеями вы можете обращаться к Сергею И.Моисеенко msi77[@]yandex.ru. Вы также можете предложить свои задачи для публикации на сайте.

    Подписка Subscribe.Ru
    Новости сайта "Упражнения по SQL"

    В избранное