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

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


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

Выпуск 258 от 05 сентября 2009 г.

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

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

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

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

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


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

§ Как заметил Arni, сбилась проверка задачи 57, в результате чего проходили не вполне верные решения. Исправил.

§ На sql-tutorial.ru появилась консоль, с помощью которой можно адресовать запросы не только к SQL Server, но и к MySQL. На очереди PostgreSQL.

§ Продолжалась работа над сервисом Моделирование. Спасибо за ваши замечания, которые помогли нам устранить ряд багов.

§ Изменения среди лидеров (решенные за неделю задачи третьего этапа):
10. Faust_zp (143)

§ Продвинулись в рейтинге:
55. Oxana (134, 77.831)
56. Wiedzmen (137, 31.119)
63. Fomichev (133, 24.581)
69. MeVit (133, 32.418)
75. Romul_T (128, 166.648)
86. Eka (125, 20.538)
97. Ashton (123, 26.597)

§ Новые лица в ТОР 100 и вернувшиеся туда:
95. alx_ol (123, 167.678)
96. Corleone (122, 6.848)
100. Eagleoff (121, 13.466)

§ Продвижение ближайших претендентов на попадание в ТОР 100:
103. vitaliiS (121, 110.854)
123. Sergey79 (118, 566.328)
125. Vezyr (115, 25.558)
149. _ORA_ (115, 104.488)
158. Magnetic (114, 140.177)
163. Mathematician (112, 2.408)

§ На этой неделе сертифицированы:
GANRIK (A09052001) [BK] - г.Рязань, Россия
Arni (A09037959) [BK] - г.Краснокамск, Россия
Поганка (A09034402) [BK] - г.Москва, Россия

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

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

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

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

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

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

No Person Number of
Sel_ex
Last_Sel Number of
DML_ex
Scores Days Days_2 Days_3 S_3 LastSolved LastVisit
1Умрихина Е.В. (Umrikhina)11601612238848941.36258.7766526 Aug 2009 04 Sep 2009
2Креславский О.М. (Arcan)116016122388937102.98984.3756524 Aug 2009 04 Sep 2009
3Зотов П.Г. (Ozzy)115816121381532190.678206.3966524 Aug 2009 04 Sep 2009
4Сальников С.А. ($erges)1159161223855475.3605.5836226 Aug 2009 04 Sep 2009
5Карасёва Н.В. (vlksm)115916122385121498.55569.1576201 Sep 2009 01 Sep 2009
6Дроздков А.Н. (anddros)5159161223844647.4798.0466103 Sep 2009 04 Sep 2009
7Сенкевич С.В. (GreyC)11411522135135857.86027.1024426 Jan 2009 29 Jul 2009
8Селезнёв А.С. (Артём С.)11391522134544447.24837.5244425 Jan 2009 03 Mar 2009
9Никотин В.М. (@Nikotin)1142150213482838.3713.7513806 Jun 2009 03 Sep 2009
10Яцук А.А. (Faust_zp)101521612236194193.458648.4953802 Sep 2009 04 Sep 2009
11Печатнов В.В. (pvv)11511612135967937.01119.9733728 Aug 2009 04 Sep 2009
12Мурашкин И.В. (lepton)113515621331113969.49059.0053605 May 2009 29 Aug 2009
13Муллаханов Р.Х. (rem)91451522235064914.62720.0563320 Jun 2009 03 Aug 2009
14Шиндин А.В. (AlShin)10136150213357920.4587.2032805 Jan 2009 25 May 2009
15Анисимов Д. (danilko)13148160223483212.7229.5422812 Aug 2009 17 Aug 2009
16Держальцев В.А. (MadVet)712814621315150960.78328.4822603 Jun 2009 16 Jun 2009
17Любченко В.А. (IAS56)6138146213321048420.338373.6172618 Jul 2009 28 Jul 2009
18Тарасов Д.Б. (Gavrila)1614716122348146643.76813.1642531 Aug 2009 04 Sep 2009
19Голубин Р.С. (Roman S. Golubin)313214521321141393.16258.8222301 Jul 2009 11 Jul 2009
20>Nikolaenko A.V. (Shadow77)12143962233875380.86314.0102104 Sep 2009 04 Sep 2009

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

No surname n_sel sel_all sel_scores dml_scores scores rating last_visit
1Бичев К. (gdengam)2938583593119203 Sep 2009
2>Contrario (bat77)283858967184704 Sep 2009
3>Заворотнев В.В. (vvz)175021335493004 Sep 2009
4Peredkov K.S. (crazibill)252652153368202 Sep 2009
5SubUrbano (Saloio)181837946453804 Sep 2009
6Oliveira J.G. (jorge_oliveira)161633942504804 Sep 2009
7>badm (badm)242441041519704 Sep 2009
8Ferreira P. (kyoujin)181837340538104 Sep 2009
9>Воевуцкий С.А. (SergLK)225935338126104 Sep 2009
10Tiago (tiago)171734135606104 Sep 2009
11>Бичев А.В. (Arcady)171934034225104 Sep 2009
12>Макеев И. (IgorM)20492933292904 Sep 2009
13Paul P. (paulpacurar[YIM])1681282949403 Sep 2009
14>Курынов Д.А. (Thistle)33326291461104 Sep 2009
15Слюсаренко М.Д. (Robin Bobin)15672702753203 Sep 2009
16>Ilyina (Pilma)99131427586104 Sep 2009
17Ефимова О.Ю. (Эльга)13672512654104 Sep 2009
18>Левитин И.А. (Spider244)15512502588204 Sep 2009
19>Nikolaenko A.V. (Shadow77)12143181192004 Sep 2009
20>Киракосянц Виталий (Robb)8721901944104 Sep 2009
21>Наумкин М.Ю. (МихаилЮ)114519019181504 Sep 2009
22Верхотуров В. (v_vladimir)133619019232902 Sep 2009

Изучаем SQL

Оператор PIVOT

Моисеенко С.И.

Чтобы объяснить, что такое PIVOT, я бы начал с электронных таблиц EXCEL. В версии MS Excel 5.0 появились так называемые сводные таблицы. Сводные таблицы представляют собой двумерную визуализацию многомерных структур данных, применяемых в технологии OLAP для построения хранилищ данных. Правильней даже сказать, что это двумерные сечения трехмерных OLAP-кубов, если иметь в виду наличие на сводной таблице элемента, который называется "страница". Сводные таблицы позволяют выполнять стандартные операции с многомерными структурами, например, упоминавшееся уже сечение куба, свертку и детализацию - операцию обратную свертке.

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

Подобные свойства сводных таблиц позволяют их использовать, наряду со сводными диаграммами, в качестве клиента для визуального отображения многомерных данных, находящихся в хранилищах, поддерживаемых различными СУБД (например, MS SQL Server Analysis Services).

Чтобы пояснить сказанное примером, давайте рассмотрим такой запрос к одной из учебных баз на sql-ex.ru:

SELECT maker, type
FROM Product

результатом которого является такая таблица:

maker   type
B PC
A PC
A PC
E PC
A Printer
D Printer
A Laptop
C Laptop
A Printer
A Printer
D Printer
E Printer
B Laptop
A Laptop
E PC
E PC

Пусть теперь нам требуется получить таблицу со следующими заголовками:

      Типы продукции
    Laptop PC Printer
П А
р B
о C
и D
з E
в.

Заголовками строк здесь являются уникальные имена производителей, которые берутся из столбца maker вышеприведенного запроса, а заголовками столбцов - уникальные типы продукции (соответственно, из столбца type). А что должно быть в середине? Ответ очевиден - некоторый агрегат, например, функция count(type), которая подсчитает для каждого производителя отдельно число моделей ПК, ноутбуков и принтеров, которые и заполнят соответствующие ячейки этой таблицы.

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

Можно сказать, что pivot-таблица - это одноуровневая сводная таблица.

Оператор PIVOT не является стандартным (я не уверен, что он когда-нибудь будет стандартизован ввиду нереляционной природы pivot-таблицы), поэтому я буду использовать в примерах его реализацию в языке T-SQL (SQL Server 2005/2008).

Я могу и ошибиться в хронологии, но мне представляется, что успех реализации сводной таблицы в Excel привел к появлению так называемых перекрестных запросов в Access, и, наконец, к оператору PIVOT в T-SQL.

Давайте рассмотрим такую задачу.

Пример 1. Для каждого производителя из таблицы Product определить число моделей каждого типа продукции.

Задачу можно решить стандартными средствами с использованием оператора CASE:

SELECT maker,
SUM(CASE type WHEN 'pc' THEN 1 ELSE 0 END) PC
, SUM(CASE type WHEN 'laptop' THEN 1 ELSE 0 END) Laptop
, SUM(CASE type WHEN 'printer' THEN 1 ELSE 0 END) Printer
FROM Product
GROUP BY maker

А вот
решение через PIVOT
(это были стихи :-), a теперь проза):

SELECT maker, -- столбец (столбцы), значения из которого формируют заголовки строк
[pc], [laptop], [printer] -- значения из столбца, который указан в предложении type,
        -- формирующие заголовки столбцов
FROM Product -- здесь может быть подзапрос
PIVOT -- формирование пивот-таблицы
(COUNT(model) -- агрегатная функция, формирующая содержимое сводной таблицы
FOR type -- указывается столбец, уникальные значения в котором будут являться заголовками столбцов
IN([pc], [laptop], [printer]) --указываются конкретные значения в столбце type,
         -- которые следует использовать в качестве заголовков,
         -- т.к. нам могут потребоваться не все
) pvt -- алиас для сводной таблицы

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

Пример 2. Посчитать среднюю цену на ноутбуки в зависимости от размера экрана.

Задача элементарная и решается с помощью группировки:

SELECT screen, AVG(price) avg_
FROM Laptop
GROUP BY screen
 
screen  avg_
11 700.00
12 960.00
14 1175.00
15 1050.00

А вот как можно повернуть эту таблицу с помощью PIVOT:

SELECT [avg_],
 [11],[12],[14],[15]
 FROM (SELECT 'average price' AS 'avg_', screen, price FROM Laptop) x
 PIVOT
 (AVG(price)
 FOR screen
 IN([11],[12],[14],[15])
 ) pvt
 
avg_     11   12   14   15
average price 700.00 960.00 1175.00 1050.00

В отличие от сводных таблиц, в операторе PIVOT требуется явно перечислить столбцы для вывода. Это серьезное ограничение, т.к. требуется знать вид данных, а значит и применять в приложениях этот оператор мы сможем, как правило, только к справочникам (вернее, к данным, которые берутся из справочников).

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

Я написал этот опус в помощь тем, кому оператор PIVOT интуитивно непонятен. Могу согласиться в том, что в реляционном языке SQL он выглядит инородным телом. Собственно, иначе и быть не может ввиду того, что поворот (транспонирование) таблицы является не реляционной операцией, а операцией работы с многомерными структурами данных.

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

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

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

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

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

Контакты

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

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

В избранное