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

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


Новости сайта "Упражнения по SQL (http://www.sql-ex.ru)" Выпуск 212 (18 октября 2008 г.)

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

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

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

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

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


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

§ Продолжается народное голосование в рамках Премии Рунета. Поддержите сайт своими голосами! Голосовать можно раз в сутки одновременно за <=50 проектов.

§ anddros заметил расхождение в рейтинговых баллов с реальным положением вещей. Исправил.

§ Поменял коллацию на базе проверки 88 задачи. Заменил устаревшую схему для SQL Server (с префиксом SQL) на аналогичную схему для Windows.
Странно, что старая коллация негативно сказывалась только выборочно.

§ Изменения среди лидеров (решенные за неделю задачи третьего этапа):
8. @Nikotin (140 - 145)
16. anddros (145)
34. Umrikhina (140)

§ Новые лица в ТОР 100 и вернувшиеся туда:
49. TimonSP (136, 2.623)
98. MeVit(125, 27.500)

§ Продвинулись в рейтинге:
44. Angellore (137, 129.598)
51. Oxana (136, 59.271)
60. glassman (133, 48.649)
64. Eka (132, 15.078)
71. Bulldozer (130, 186.840)
72. Botch (129, 19.922)
74. shadon (129, 29.962)
84. SoVa (126, 255.689)

§ Продвижение ближайших претендентов на попадание в ТОР 100:
102. lexaNRJ (125, 88.113)
113. Pavel_yu (124, 132.199)
118. Ashton (122, 18.590)
121. Tunin (119, 35.931)
133. mar_vi (120, 6.551)

§ На этой неделе сертифицированы:
Dfg5 (A08029002) [BK] - г.Москва, Россия
Magnetic (A08027667) [BK] - г.Киев, Украина
fitu (A08039017) [BK] - г.Минск, Беларусь
Умклайдет (A08022362) [BK] - г.Москва, Россия
enull (A08039096) [BK] - г.Москва, Россия
TimonSP (B08039081) [AR] - г.Саратов, Россия

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

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

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

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

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

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

No Person Number of
Sel_ex
Last_Sel Number of
DML_ex
Scores Days Days_2 Days_3 S_3 LastSolved LastVisit
1 Печатнов В.В. (pvv) 149 149 21 360 357 30.865 17.490 36 10 Oct 2008 17 Oct 2008
2 Селезнёв А.С. (Артём С.) 148 149 21 357 322 38.520 29.235 36 25 Sep 2008 16 Oct 2008
3 Креславский О.М. (Arcan) 149 149 21 360 617 48.147 36.296 36 08 Oct 2008 16 Oct 2008
4 Карасёва Н.В. (vlksm) 149 149 21 360 866 77.240 49.173 36 18 Sep 2008 17 Oct 2008
5 Сальников С.А. ($erges) 148 149 21 358 196 2.854 3.359 34 09 Sep 2008 17 Oct 2008
6 Держальцев В.А. (MadVet) 140 146 21 341 1257 60.815 28.482 28 24 Sep 2008 06 Oct 2008
7 Любченко В.А. (IAS56) 139 146 21 340 615 403.439 373.617 28 11 May 2008 16 Aug 2008
8 Никотин В.М. (@Nikotin) 145 143 21 349 49 6.299 1.414 25 15 Oct 2008 17 Oct 2008
9 Голубин Р.С. (Roman S. Golubin) 143 145 21 343 1122 93.054 58.822 25 13 Sep 2008 15 Oct 2008
10 Nikolaenko A.V. (Shadow77) 143 147 21 343 410 51.575 14.010 23 26 Sep 2008 16 Oct 2008
11 Мурашкин И.В. (lepton) 142 148 21 342 921 43.485 33.011 23 29 Sep 2008 02 Oct 2008
12 Солдатенков Ю.С. (SolYUtor) 141 146 21 339 819 22.703 6.102 20 14 Aug 2008 24 Sep 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 Войнов П.Е. (pаparome) 142 146 21 338 1125 3.132 .213 17 22 Sep 2008 07 Oct 2008
16 Дроздков А.Н. (anddros) 143 145 21 341 140 4.236 .921 17 14 Oct 2008 17 Oct 2008
17 iglbeat (iglbeat) 140 145 21 336 360 34.601 15.225 17 08 Aug 2008 25 Aug 2008
18 Северюхин Ю.А. (Venser) 131 142 21 319 335 4.925 .655 14 01 Feb 2008 04 Feb 2008
19 Борисенков Д.В. (xuser) 139 142 21 331 254 3.318 .926 14 11 Oct 2008 17 Oct 2008
20 Мишин С.А. (CepbIu) 137 142 21 328 69 9.772 2.148 14 26 Jun 2008 10 Sep 2008

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

No surname n_sel sel_all sel_scores dml_scores scores rating last_visit
1 Барцев (bartsev) 35 35 67 17 84 2114 17 Oct 2008
2 >ерохин (sql-er) 30 42 66 0 66 2326 17 Oct 2008
3 >Бавтрук (_irina_) 32 36 65 0 65 2945 16 Oct 2008
4 >Черняев (breezemaster1) 20 82 49 15 64 447 17 Oct 2008
5 >Азбель Е. (enull) 11 77 27 34 61 393 17 Oct 2008
6 >zubovich (zn) 15 49 29 32 61 1027 17 Oct 2008
7 >Ларионов И.В. (CKY4HO) 27 41 61 0 61 2385 17 Oct 2008
8 >Грызунов Р.М. (gryzunov) 32 32 61 0 61 3492 17 Oct 2008
9 Vildanov M. (mar_vi) 23 120 57 0 57 133 17 Oct 2008
10 pq17 (pq-17) 24 24 49 6 55 3965 17 Oct 2008
11 >Михайличенко Д.А. (Deanit) 20 31 45 9 54 3120 17 Oct 2008
12 >gremlin (gremlin1) 20 31 49 0 49 2300 17 Oct 2008
13 >d C. (delia.ciripan) 17 29 41 8 49 2691 17 Oct 2008
14 >Zolotarev (SergZ) 5 76 12 34 46 409 17 Oct 2008
15 >Olizarovich (Yuriy.O) 18 32 44 0 44 3507 17 Oct 2008
16 Меньшенин В.А. (Volting) 20 32 44 0 44 3815 16 Oct 2008
17 >T T.T. (lesha) 24 24 44 0 44 5144 17 Oct 2008
18 Панзин М.А. (miсpan) 3 67 8 34 42 585 17 Oct 2008
19 >Соколов А. (innominate) 19 25 41 0 41 4847 17 Oct 2008
20 serg (sergey25) 14 37 35 4 39 1856 17 Oct 2008
21 Ябжанов В. (yabsql) 5 53 9 29 38 906 16 Oct 2008
22 popova (pragma) 15 25 37 0 37 4753 17 Oct 2008
23 Баулин И.А. (60cx) 15 27 36 0 36 4660 15 Oct 2008
24 >Аблитаров (Ильяс) 13 26 33 0 33 4638 17 Oct 2008
25 Smartov (qmsatr) 13 28 32 0 32 4501 12 Oct 2008
26 Перевертайло Р.А. (Fenix_PR) 18 18 31 0 31 6709 17 Oct 2008

Изучаем SQL

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

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

iii. TOP OVER

Опция TOP для запроса была введена в SQL Server 7.0 как нестандартное расширение T-SQL. TOP широко используется, так как эта опция отвечает практической потребности. Однако чувствуется, что конструкция TOP неудачна, неполна и не соответствует духу стандарта SQL. Но, хотя TOP и нет в стандартном SQL, эту конструкцию можно переделать "в духе стандарта". Мы чувствуем, что ввод поддержки для TOP с предложением OVER сгладит имеющиеся сейчас шероховатости и ограничения.

В настоящее время конструкция TOP используется в некрасивой связке с предложением ORDER BY; смысл предложения ORDER BY иногда неоднозначен и приводит к запутанности и ограничениям. Например, рассмотрим следующий запрос:

USE Northwind;

SELECT TOP(3) OrderDate, OrderID, CustomerID, EmployeeID
FROM dbo.Orders
ORDER BY OrderDate DESC, OrderID DESC;

Предложение ORDER BY здесь служит двум разным целям:
1. логической: служит в качестве фильтра для опции TOP.
2. презентационной: возвращает строки в выходной поток в указанном порядке - скорее результат курсора, чем множество записей.

Факт такого обслуживания двух разных целей проблематичен. Может быть, вам нужно было выбрать данные по одному критерию, а вывести данные, упорядоченные по другому критерию (или вовсе неупорядоченные). Также, многие программисты не понимают, что когда вы используете запрос с TOP для того, чтобы определить табличное выражение (представление, однострочную табличную функцию, производную таблицу, CTE), предложение ORDER BY теряет свою функцию представления результата. Например, в следующем запросе:

SELECT *
FROM (SELECT TOP(3) OrderDate, OrderID, CustomerID, EmployeeID
      FROM dbo.Orders
      ORDER BY OrderDate DESC, OrderID DESC) AS D;

нет гарантии, что результирующие записи будут выведены в определенном порядке (даже если с точки зрения оптимизации так должно быть). Это недоразумение приводит к абсурдному использованию опции TOP, например, "сортированным представлениям":

CREATE VIEW dbo.SortedOrders
AS

SELECT TOP(100) PERCENT OrderDate, OrderID, CustomerID, EmployeeID
FROM dbo.Orders
ORDER BY OrderDate DESC, OrderID DESC;

Многие программисты не понимают, что следующий запрос НЕ возвращает гарантированно упорядоченные записи:

SELECT * FROM dbo.SortedOrders;

и что такое использование ORDER BY - абсурд. К сожалению, графические инструменты SQL Server укрепляют это абсурдное поведение, предоставляя кнопку сортировки в графическом конструкторе - если нажать кнопку, конструктор добавляет TOP (100) PERCENT и предложение ORDER BY в определение представления.

Эта неоднозначность предложения ORDER BY привела к некоторым ограничениям в T-SQL. Например, вы не можете задать теоретико-множественную операцию с двумя запросами, каждый из которых содержит TOP с предложением ORDER BY:

SELECT TOP … FROM T1 ORDER BY col1
UNION ALL
SELECT TOP … FROM T2 ORDER BY col1

Причина в том, что внешний запрос с предложением ORDER BY возвращает курсор, а не множество записей, тогда как теоретико-множественные операторы действуют на множествах, а не на курсорах.

Кроме того, операторы модификации данных с опцией TOP не допускают использования предложения ORDER BY. Следующие оператор DELETE является недетерминистическим:

DELETE TOP (50) FROM dbo.Orders;

Вы не можете сказать, какие записи будут удалены. Конечно, на практике, скорее всего, будет такое задание: удалить 50 самых старых заказов, но вы не сможете достичь этого посредством опции TOP в операторе delete.

Помимо нечеткого смысла предложения ORDER BY, который зависит от контента, есть и другие проблемы, связанные с TOP. В настоящее время для TOP не поддерживается разбиение на группы (partitioning); например, вы можете вывести 3 последние заказа вообще, но не 3 последние заказа для каждого работника.

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

WITH C AS
(
  SELECT
    ROW_NUMBER() OVER(ORDER BY OrderDate DESC, OrderID DESC) AS RowNum,
    OrderDate, OrderID, CustomerID, EmployeeID
  FROM dbo.Orders
)
SELECT *
FROM C
WHERE RowNum <= 3;

Здесь у вас нет необходимости использовать ORDER BY для представления результата, а если вы и захотите его использовать, то это предложение ORDER BY не обязано быть таким же, как логическое ORDER BY:

WITH C AS
(
  SELECT
    ROW_NUMBER() OVER(ORDER BY OrderDate DESC, OrderID DESC) AS RowNum,
    OrderDate, OrderID, CustomerID, EmployeeID
  FROM dbo.Orders
)
SELECT *
FROM C
WHERE RowNum <= 3
ORDER BY CustomerID;

Вот здесь разделение (partitioning) было бы естественным. Например, возвратить 3 самых последних заказа для каждого работника:

WITH C AS
(
  SELECT
    ROW_NUMBER() OVER(PARTITION BY EmployeeID
                      ORDER BY OrderDate DESC, OrderID DESC) AS RowNum,
    OrderDate, OrderID, CustomerID, EmployeeID
  FROM dbo.Orders
)
SELECT *
FROM C
WHERE RowNum <= 3;

Эта логика также поддерживается и для операторов модификации. Например, удалить 50 самых старых заказов:

WITH C AS
(
  SELECT
    ROW_NUMBER() OVER(ORDER BY OrderDate, OrderID) AS RowNum,
    OrderDate, OrderID, CustomerID, EmployeeID
  FROM dbo.Orders
)
DELETE FROM C
WHERE RowNum <= 50;

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

SELECT
  TOP(3) OrderDate, OrderID, CustomerID, EmployeeID
    OVER(ORDER BY OrderDate DESC, OrderID DESC)
FROM dbo.Orders;

Здесь вы не обязаны использовать презентационный ORDER BY, а если вдруг захотите, то это упорядочение не обязано быть таким же, как в логическом ORDER BY:

SELECT
  TOP(3) OrderDate, OrderID, CustomerID, EmployeeID
    OVER(ORDER BY OrderDate DESC, OrderID DESC)
FROM dbo.Orders
ORDER BY CustomerID;

Такая поддержка также позволила бы использовать теоретико-множественный подход для TOP-запросов с логическим ORDER BY.

SELECT TOP … OVER(ORDER BY col1) FROM T1
UNION ALL
SELECT TOP … OVER(ORDER BY col1) FROM T2;

Как и при всех других использованиях предложения OVER, разбиение здесь было бы естественным. Например, для того, чтобы вывести 3 самых последних заказа для каждого работника, вы использовали бы

SELECT
  TOP(3) OrderDate, OrderID, CustomerID, EmployeeID
    OVER(PARTITION BY EmployeeID
         ORDER BY OrderDate DESC, OrderID DESC)
FROM dbo.Orders;

Эта логика также пригодилась бы для модификаций на основе ТОР с логическим ORDER BY. Например, для удаления 50 самых старых заказов, вы использовали бы:

DELETE TOP(5) OVER(ORDER BY OrderDate, OrderID)
FROM C;

Добавление такой поддержки не должно породить проблемы обратной совместимости, поскольку парсеру должно быть понятно, когда использована старая опция TOP, а когда новая (при заданном предложении OVER). Как только такая поддержка будет добавлена, поддержание старой опции TOP можно постепенно свести на нет, и благополучно и окончательно исключить в одной из будущих версий.

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

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

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

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

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

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

Контакты

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

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

В избранное