Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
мет_ОБД.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
1.92 Mб
Скачать

In (список_імен_стовпців_значень_груп)

псевдонім_таблиці |

table_source UNPIVOT (ім'я_стовпця_обчисл FOR ім'я_стовпця_угруповання

In (список_імен_стовпців))

псевдонім_таблиці |

@ім'я_змінної [ [as] псевдонім ] |

@ім'я_змінної.виклик_функції(аргументи) [ [as] псевдонім ]

[(псевдоніми_стовпців)]

}

Розглянемо деякі можливі значення table_source:

  1. Ім'я таблиці або подання. Можливе завдання псевдоніма. При цьому ім'я може описуватися як завданням всіх 4-ьох його компонентів, так і частковим їх використанням. Слід зазначити появу в MS SQL Server 2005 конструкції TABLESAMPLE, таким чином, використання цієї конструкції припустимо, якщо рівень сумісності для БД виставлений у значення 90. Вона призначена для «випадкової» вибірки зазначеного числа (приблизно) відсотків рядків (ключове слово PERCENT - значення за замовчуванням) або рядків (ключове слово ROWS). Ключове слово SYSTEM описує єдино доступний на даний момент спосіб «випадкової» вибірки, причому є значенням за замовчуванням. Слід зазначити, що у випадку маленьких таблиць (десятки або сотні рядків) і малого розміру вибірки можлива ситуація, коли при виконанні команди вертаються або всі рядки таблиці або порожня множина, причому ймовірність одержання всіх рядків пропорційна розміру «випадкової» вибірки. Ключове слово REPEATABLE, за яким іде ідентифікатор «випадкової» вибірки, призначене для повторного одержання заданої випадкової вибірки. Якщо його не використовувати, то при повторному виконанні команди SELECT з конструкцією TABLESAMPLE може бути отримана інша «випадкова» вибірка.

  2. Системна або користувальницька функція, що повертає набір рядків.

  3. Вкладений SQL запит (команда SELECT), що повертає деяку множину рядків.

  4. Вертикальне об'єднання 2-ух і більше таблиць (JOIN). По суті - вертикальне об'єднання є декартовим добутком, тобто множиною різних об'єднань пара рядків для зазначених таблиць. Воно часто застосовується для об'єднання двох і більше таблиць, зв'язаних обмеженням FOREIGN KEY. В MS SQL Server 2005 (як і в MS SQL Server 2000) існує 5 різних типів таких об'єднань всіх можливих пар рядків (слід зазначити, що поєднуються тільки ті стовпці таблиць, які перебувають в select_list):

    1. об'єднання по певній умові, які виконуються в такий спосіб (якщо не зазначений тип об'єднання, то за замовчуванням мається на увазі INNER JOIN):

      • INNER JOIN - для кожної строки таблиці із правої частини оператора об'єднання по черзі вибирається рядок з таблиці лівої частини оператора об'єднання, що задовольняє умові.

      • LEFT OUTER JOIN - для кожної строки таблиці з лівої частини оператора об'єднання по черзі вибираються рядок з таблиці правої частини оператора об'єднання, що задовольняє умові. Якщо такого рядка нема, то беруться значення NULL для всіх обираних стовпців «правої» таблиці.

      • RIGHT OUTER JOIN - для кожної строки таблиці із правої частини оператора об'єднання по черзі вибирається рядок з таблиці лівої частини оператора об'єднання, що задовольняє умові. Якщо такого рядка нема, то беруться значення NULL для всіх обираних стовпців «лівої» таблиці.

      • FULL OUTER JOIN - для кожної строки таблиці з лівої частини оператора об'єднання по черзі вибирається рядок з таблиці правої частини оператора об'єднання, що задовольняє умові. Якщо такого рядка нема, то беруться значення NULL для всіх обираних стовпців «правої» таблиці. Далі, беруться рядки «правої» таблиці, не задовольняючі умові, і доповнюються значеннями NULL для обираних стовпців «лівої» таблиці.

    2. CROSS JOIN - виконується так: для кожної строки таблиці із правої частини оператора об'єднання по черзі вибирається рядок з таблиці лівої частини оператора об'єднання. Еквівалентно перерахуванню джерел даних через кому.

    3. об'єднання за допомогою оператора {CROSS | OUTER} APPLY. Цей оператор об'єднання уведений в MS SQL Server 2005, таким чином, його використання припустиме, якщо рівень сумісності для БД виставлений у значення 90. Особливістю використання цього оператора є те, що в якості «правої» таблиці може виступати функція, що повертає множини рядкків, що як аргумент одержує значення стовпця «лівої» таблиці. Слід зазначити, що «ліве» джерело даних може також включати функцію, що повертає множин рядків, однак ця функція не може одержувати значення стовпця з «правої» таблиці як свій аргумент. Розглянемо докладніше два можливих види оператора APPLY:

  • CROSS - результатом є всі пари рядків отриманих у результаті об'єднання множині рядків, отриманих функцією, з множиною рядків «лівої» таблиці. Причому, якщо для якого або значення аргументу, що повертається функцією множина рядків є порожньою, то в цьому випадку нові рядки не генеруються.

  • OUTER - результатом є все пари рядків отриманих у результаті об'єднання множини рядків, отриманих функцією, з множиною рядків «лівої» таблиці. Причому, якщо для якого або значення аргументу, що повертається функцією множина рядків є порожньою, то в цьому випадку нові рядки виходять шляхом об'єднання рядка з «лівої» таблиці зі значеннями NULL для обираних стовпців з множини рядків, що повертаються «правої» функцією.

  1. Угруповання (з «розворотом») рядків таблиці (оператор PIVOT). Його використання припустиме, якщо рівень сумісності для БД виставлений у значення 90. Цей оператор здійснює угруповання по стовпці, ім'я якого вказується після ключового слова FOR. Потім, для кожної групи, значення яких повинні бути зазначені в select_list і в переліку імен стовпців після ключового слова IN генерується значення, які повертає агрегаційна функція. Ці значення формують рядки, які вертаються подібною командою SELECT. Причому, заголовки стовпців цих рядків збігаються з іменами стовпців після ключового слова IN. Якщо яка-небудь група відсутня (тобто серед значень стовпця угруповання немає такого значення, що входить у множини значень після ключового слова IN), то у відповідному стовпці виводиться значення NULL (якщо агрегаційна функція - count, то виводиться 0). Слід зазначити, що при використанні оператора PIVOT над аргументом агрегаційної функції, що є ім'ям стовпця, не можна виконувати перетворення типу за допомогою функцій CAST і CONVERT.

  2. Зворотний «розворот» стовпців таблиці (оператор UNPIVOT). Виконує, по суті, дія зворотню операторові PIVOT (за винятком одержання наборів рядків, які утворювали кожну групу). Його використання припустиме, якщо рівень сумісності для БД виставлений у значення 90. Він виконує «розворот» таблиці, так що стовпці стають рядками, а рядки - стовпцями (подібно транспонуванню матриці). Таким чином, значення стовпця, ім'я якого вказується після оператора UNPIVOT (він був аргументом агрегаційної функції в операторі PIVOT) формують різні значення для груп. Їх назви формуються значеннями стовпця, ім'я якого задане після ключового слова FOR, а перелік можливих значень заданий після ключового слова IN. Одержувана таблиця не містить «порожніх» груп (для яких оператор PIVOT генерував значення NULL(0)).

Секція WHERE.

Після ключового слова WHERE іде умова пошуку, відповідно до виконання (істинністю) якого приймається рішення про добування чергового рядка із джерела даних (таблиць(і)) командою SELECT. Слід зазначити, що умова може включати логічні операції NOT, AND, OR, LIKE, BETWEEN, IS [NOT] NULL, ALL, SOME, ANY, EXISTS, операції порівняння, FREETEXT, вкладені запити SELECT.

Секція GROUP BY.

Використання цієї секції приводить до угруповання результуючої множини рядків по обраних стовпцях. У загальному виді виглядає в такий спосіб:

GROUP BY [ALL] список_стовпців_по_яких_відбувається_угруповання

[WITH {CUBE | ROLLUP}]

Опція ALL примушує використовувати при формуванні груп навіть ті рядки, які були відкинуті в секції WHERE, тому що не задовольняли умові пошуку. Однак ALL не можна використовувати з опціями WITH CUBE або WITH ROLLUP, а також при звертанні до вилучених таблиць, якщо використовується секція WHERE.

Стовпці, по яких здійснюється угруповання, не можуть мати типів даних text, ntext і image. Якщо опції WITH CUBE або WITH ROLLUP не використовуються, то кількість стовпців обмежується тільки їхньою сумарною довжиною, що не повинна перевищувати 8060 байт. Якщо ж опції WITH CUBE або WITH ROLLUP використовуються, то максимальна кількість стовпців, по яких здійснюється угруповання, не може перевищувати 10. Слід зазначити, що перелік стовпців, по яких відбувається угруповання, повинен бути повністю включений в select_list секції SELECT, причому використовувати символ * стає неможливим.

Опція WITH CUBE для кожної групи генерує рядки, що мають усілякі комбінації значень NULL для групоутворюючих стовпців.

Опція WITH ROLLUP для кожної одержуваної групи генерує значення NULL, таким чином, щоб були отримані набори рядків виду: (c1, c2, ..., cn-1, NULL), (c1, c2, ..., NULL, NULL), (c1, c2, ..., cn-3, NULL, NULL, NULL), ..., (NULL, ... NULL), де c1, c2, ..., cn - імена групоутворюючих стовпців.

Секція HAVING.

Аналогічно секції WHERE, але застосовується для груп, отриманих у результаті використання секції GROUP BY. Якщо GROUP BY не використовується, то повністю еквівалентно WHERE, але спрацьовує після нього. У секції HAVING не можна використовувати дані типів text, ntext і image. Якщо секція GROUP BY використовується з опцією ALL, то секція HAVING «заміщає» (має можливість обмежити кількість рядків) дію цієї опції.

Оператори UNION, EXCEPT і INTERSECT.

Ці оператори призначені для здійснення горизонтального об'єднання двох і більше множин рядків. При горизонтальних об'єднаннях кількість стовпців у поєднуваних множинах рядків повинна бути однаковою, а типи даних для відповідних стовпців повинні бути сумісні або неявно приводитись один до іншого.

Оператор UNION [ALL] виконує просте об'єднання двох множин рядків, причому використання опції ALL приводить до того, що рядки, що дублюються, зберігаються, у противному випадку - з кожного набору рядків, що дублюються, залишається тільки один.

Оператори EXCEPT і INTERSECT не можуть використовуватися зі стовпцями (виразами), які мають типи даних xml, text, ntext, image, а також користувальницькі типи даних, які не приводяться до типу varbinary. Використання цих операторів припустимо, якщо рівень сумісності для БД виставлений у значення 90. Якщо використовується секція ORDER BY, то в ній повинні використовуватися імена стовпців із запиту SELECT лівої частини оператора EXCEPT або INTERSECT.

За допомогою оператора EXCEPT вибираються неповторювані рядки з результуючої множини рядків «лівого» запиту, які відсутні в результуючій множині рядків «правого» запиту.

За допомогою оператора INTERSECT вибираються неповторювані рядки з результуючої множини рядків «лівого» запиту, які входять і в результуючу множину рядків «правого» запиту.

Секція ORDER BY.

У цій секції здійснюється впорядкування одержуваної множині рядків, і вона має такий загальний вигляд:

ORDER BY назва_стовпця__або__синонім_назви_стовпця

[COLLATE назва]

[ {ASC | DESC} ]

[, і т.п.]

Варто врахувати, що стовпець, по якому відбувається впорядкування результуючої множини рядків, може бути виразом, але цей вираз не повинен давати константне значення в результаті свого обчислення, а також не повинен містити функцій ад'єктивування (наприклад, avg, sum, min, max і т.п.). У переліку імен стовпців секції ORDER BY можуть бути стовпці, які відсутні в select_list, однак це можливо, якщо не використовується опція DISTINCT, і якщо відсутні секції GROUP BY і UNION. Крім того, якщо використовується оператор UNION, то в переліку імен стовпців ORDER BY можуть вказуватися тільки імена або псевдоніми стовпців з select_list 1-ої з поєднуваних команд SELECT. Слід також зазначити, що стовпці, використовувані в переліку ORDER BY, не можуть мати типи даних text, ntext і image.

Опція COLLATE задає назву (collation name) кодової сторінки і, відповідно, правила упорядкування символів і застосовна тільки для стовпців, що мають типи даних char, nchar, varchar, nvarchar.

Опції ASC(за замовчуванням) або DESC задають тип сортування: по зростанню або по убуванню.

Слід зазначити, що значення NULL інтерпретуються як мінімально можливі. Кількість імен або псевдонімів стовпців у переліку ORDER BY не обмежено, але існує обмеження на сумарну довжину одного рядка тимчасової таблиці, використовуваної для сортування. Воно становить 8060 байт.

Секція COMPUTE.

Ця секція призначена для одержання і виводу деякої статистичної інформації про отриману у результаті виконання команди SELECT множину рядків і в загальному випадку виглядає так:

COMPUTE

{avg | count | max | min | stdev | stdevp | var | varp | sum}

(вираз) [, і т.п.]

[BY вираз [, і т.п.] ]

Таким чином, COMPUTE здійснює вивід рядка, що містить статистичну інформацію, отриману за допомогою якоїсь(якихось) із припустимих агрегаційних функцій, як аргумент якої(яких) виступає вираз, що містить стовпці таблиці. Ця статистична інформація генерується або для всієї множини одержуваних рядків, або для груп рядків (угруповання відбувається у випадку використання опції BY, після якої йде список імен стовпців, по яких формуються групи).

Слід зазначити, що стовпці, використовувані в секції COMPUTE, не можуть мати типи даних text, ntext, image. Також, у випадку використання COMPUTE, необхідно застосовувати впорядкування, виконане в секції ORDER BY. Причому список імен стовпців секції COMPUTE повинен містити тільки стовпці, використовувані в секції ORDER BY, хоча не всі стовпці, використовувані в секції ORDER BY, повинні міститися в секції COMPUTE.

Приклади роботи команди SELECT.

Для деяких прикладів буде використані дві таблиці: table1 і table2.

Таблиця table1 створена в такий спосіб:

CREATE TABLE table1 (c1 int, c2 int, c3 int primary key identity)

Аналогічно створена таблиця table2:

CREATE TABLE table2 (c1 int, c2 int, c3 int primary key identity)

Вміст таблиць table1 і table2 представлено в табл. 1.

Табл. 1. Уміст таблиць table1 і table2

table1

table2

с1

с2

с3

с1

с2

с3

1

2

1

1

2

1

1

2

2

1

4

2

1

2

3

1

5

3

1

2

4

1

2

4

2

5

5

3

6

5

6

5

6

6

5

6

2

4

7

2

4

7

2

3

8

2

13

8

11

11

9

13

11

10

10

10

11

Приклад 1.

Виконання найпростішої команди SELECT:

SELECT 2+5 as EX_COL

дасть наступний результат:

EX_COL

1

7

Приклад 2.

Використання секцій FROM, ORDER BY і опцій секції SELECT.

У результаті виконання команди

SELECT DISTINCT c1, c2 FROM table1

буде отриманий наступний набір рядків:

c1

с2

1

2

2

5

6

5

2

4

2

3

11

11

13

11

10

10

тобто двох однакових рядків у результуючій множині немає.

У результаті виконання команди

SELECT DISTINCT TOP 4 c1, c2 FROM table1

будуть отримані тільки 1-і 4 рядка з множини рядків, що повертаються попередньою командою.

Якщо ж виконати таку команду

SELECT TOP 2 WITH TIES c1, c2 FROM table1 ORDER BY c1

то результуюча множина рядків буде наступною:

с1

с2

1

2

1

2

1

2

1

2

незважаючи на те, що повинні були бути отримані тільки два 1-их рядки. Це відбувається тому, що використано опцію WITH TIES, застосування якої приводить до того, що вибираються всі рядки, у яких значення в стовпцях c1 і c2 збігаються зі значеннями 2-ого рядка.

Приклад 3.

Використання секцій INTO і WHERE.

При необхідності скопіювати частину рядків таблиці table1, що задовольняють деякій умові, у нову таблицю, наприклад table3, необхідно виконати наступну команду:

SELECT * INTO table3 FROM table1 WHERE c1 > 1 and c2 != 5

У результаті виконання цієї команди таблиця table3 (не повинна існувати перед виконанням команди) буде містити наступних 5 рядків:

с1

с2

с3

2

4

7

2

3

8

11

11

9

13

11

10

10

10

11

Приклад 4.

Вертикальні об'єднання.

Всі приклади вертикальних об'єднань розглянемо з використанням таблиць table1 і table2. INNER JOIN:

SELECT * from table1 t1 JOIN table2 t2 ON t1.c2 = t2.c2

Результат (спочатку стовпці table1, потім - table2):

с1

с2

с3

с1

с2

с3

1

2

1

1

2

1

1

2

2

1

2

1

1

2

3

1

2

1

1

2

4

1

2

1

2

4

7

1

4

2

2

5

5

1

5

3

6

5

6

1

5

3

1

2

1

1

2

4

1

2

2

1

2

4

1

2

3

1

2

4

1

2

4

1

2

4

2

5

5

6

5

6

6

5

6

6

5

6

2

4

7

2

4

7

LEFT JOIN:

SELECT * from table1 t1 LEFT JOIN table2 t2 ON t1.c2 = t2.c2

Результат (спочатку стовпці table1, потім - table2):

с1

с2

с3

с1

с2

с3

1

2

1

1

2

1

1

2

1

1

2

4

1

2

2

1

2

1

1

2

2

1

2

4

1

2

3

1

2

1

1

2

3

1

2

4

1

2

4

1

2

1

1

2

4

1

2

4

2

5

5

1

5

3

2

5

5

6

5

6

6

5

6

1

5

3

6

5

6

6

5

6

2

4

7

1

4

2

2

4

7

2

4

7

2

3

8

NULL

NULL

NULL

11

11

9

NULL

NULL

NULL

13

11

10

NULL

NULL

NULL

10

10

11

NULL

NULL

NULL

RIGHT JOIN:

SELECT * from table1 t1 RIGHT JOIN table2 t2 ON t1.c2 = t2.c2

Результат (спочатку стовпці table1, потім - table2):

с1

с2

с3

с1

с2

с3

1

2

1

1

2

1

1

2

2

1

2

1

1

2

3

1

2

1

1

2

4

1

2

1

2

4

7

1

4

2

2

5

5

1

5

3

6

5

6

1

5

3

1

2

1

1

2

4

1

2

2

1

2

4

1

2

3

1

2

4

1

2

4

1

2

4

NULL

NULL

NULL

3

6

5

2

5

5

6

5

6

6

5

6

6

5

6

2

4

7

2

4

7

NULL

NULL

NULL

2

13

8

FULL JOIN:

SELECT * from table1 t1 FULL JOIN table2 t2 ON t1.c2 = t2.c2

Результат (спочатку стовпці table1, потім - table2):

с1

с2

с3

с1

с2

с3

1

2

1

1

2

1

1

2

1

1

2

4

1

2

2

1

2

1

1

2

2

1

2

4

1

2

3

1

2

1

1

2

3

1

2

4

1

2

4

1

2

1

1

2

4

1

2

4

2

5

5

1

5

3

2

5

5

6

5

6

6

5

6

1

5

3

6

5

6

6

5

6

2

4

7

1

4

2

2

4

7

2

4

7

2

3

8

NULL

NULL

NULL

11

11

9

NULL

NULL

NULL

13

11

10

NULL

NULL

NULL

10

10

11

NULL

NULL

NULL

NULL

NULL

NULL

3

6

5

NULL

NULL

NULL

2

13

8

CROSS JOIN:

SELECT * from table1 CROSS JOIN table2

що еквівалентно

SELECT * from table1, table2

Результат (спочатку стовпці table1, потім - table2):

с1

с2

с3

с1

с2

с3

1

2

1

1

2

1

1

2

2

1

2

1

1

2

3

1

2

1

1

2

4

1

2

1

2

5

5

1

2

1

6

5

6

1

2

1

2

4

7

1

2

1

2

3

8

1

2

1

11

11

9

1

2

1

13

11

10

1

2

1

10

10

11

1

2

1

1

2

1

1

4

2

1

2

2

1

4

2

1

2

3

1

4

2

1

2

4

1

4

2

2

5

5

1

4

2

6

5

6

1

4

2

2

4

7

1

4

2

2

3

8

1

4

2

11

11

9

1

4

2

13

11

10

1

4

2

10

10

11

1

4

2

1

2

1

1

5

3

1

2

2

1

5

3

1

2

3

1

5

3

1

2

4

1

5

3

2

5

5

1

5

3

6

5

6

1

5

3

2

4

7

1

5

3

2

3

8

1

5

3

11

11

9

1

5

3

13

11

10

1

5

3

10

10

11

1

5

3

1

2

1

1

2

4

1

2

2

1

2

4

1

2

3

1

2

4

1

2

4

1

2

4

2

5

5

1

2

4

6

5

6

1

2

4

2

4

7

1

2

4

2

3

8

1

2

4

11

11

9

1

2

4

13

11

10

1

2

4

10

10

11

1

2

4

1

2

1

3

6

5

1

2

2

3

6

5

1

2

3

3

6

5

1

2

4

3

6

5

2

5

5

3

6

5

6

5

6

3

6

5

2

4

7

3

6

5

2

3

8

3

6

5

11

11

9

3

6

5

13

11

10

3

6

5

10

10

11

3

6

5

1

2

1

6

5

6

1

2

2

6

5

6

1

2

3

6

5

6

1

2

4

6

5

6

2

5

5

6

5

6

6

5

6

6

5

6

2

4

7

6

5

6

2

3

8

6

5

6

11

11

9

6

5

6

13

11

10

6

5

6

10

10

11

6

5

6

1

2

1

2

4

7

1

2

2

2

4

7

1

2

3

2

4

7

1

2

4

2

4

7

2

5

5

2

4

7

6

5

6

2

4

7

2

4

7

2

4

7

2

3

8

2

4

7

11

11

9

2

4

7

13

11

10

2

4

7

10

10

11

2

4

7

1

2

1

2

13

8

1

2

2

2

13

8

1

2

3

2

13

8

1

2

4

2

13

8

2

5

5

2

13

8

6

5

6

2

13

8

2

4

7

2

13

8

2

3

8

2

13

8

11

11

9

2

13

8

13

11

10

2

13

8

10

10

11

2

13

8

Використання оператора APPLY. Для демонстрації можливостей такого оператора об'єднання напишемо функцію, що повертає набір рядків з таблиці table1, значення стовпця c2 у яких збігається з аргументом функції:

/* Перевіряємо існування функції з ім'ям func1 */

IF EXISTS (SELECT name, type FROM sys.all_objects WHERE name = 'func1'

AND type = 'FN')

/* Якщо така функція існує, то видаляємо її

DROP FUNCTION func1

- Команда створення функції повинна бути 1-ою у пакеті команд, тому виконуємо

- примусове завершення пакета за допомогою команди go

GO

/*

Створюємо функцію, що повертає значення типу TABLE - таблицю з полями за назвою і типом, що збігаються з полями таблиці table1, що вставляє в поверта_ змінну @tt1 табличного типу всі рядки таблиці table1, значення стовпця c2 у яких збігається з аргументом @c2_val.

*/

CREATE FUNCTION func1(@c2_val int) RETURNS @tt1 TABLE(c1 int, c2 int, c3 int)

AS

BEGIN

INSERT INTO @tt1 SELECT * FROM table1 WHERE c2 = @c2_val

- Обов'язкова наявність ключового слова return

RETURN

END

GO

Тепер виконаємо команди SELECT з використанням оператора об'єднання APPLY. Спочатку - CROSS APPLY:

SELECT * FROM table1 AS t1 CROSS APPLY func1(t1.c2 + 1)

у результаті чого одержуємо:

с1

с2

З3

с1

с2

с3

1

2

1

2

3

8

1

2

2

2

3

8

1

2

3

2

3

8

1

2

4

2

3

8

2

4

7

2

5

5

2

4

7

6

5

6

2

3

8

2

4

7

10

10

11

11

11

9

10

10

11

13

11

10

Якби результати цієї команди потрібно було б перенести в таблицю, то це можна було б зробити, використовуючи вкладений запит SELECT, у такий спосіб:

SELECT * INTO cross_apply FROM

(SELECT t1.*, t2.c1 AS cc1, t2.c2 AS cc2, t2.c3 AS cc3

FROM table1 AS t1 CROSS APPLY func1(t1.c2 + 1) AS t2) AS tt2

Слід зазначити, що складність написання вищерозглянутої команди полягає в тому, що в результаті знаходження об'єднання таблиці table1 і результатів роботи функції func1 виходить 3 пари полів з однаковими назвами, що не дозволяє записати результат виконання цього запиту в нову таблицю за допомогою секції INTO зовнішньої команди SELECT. Для вирішення конфлікту імен доводиться для кожного імені, що дублюється, описувати синонім у вкладеній команді SELECT.

Тепер розглянемо приклад використання оператора об'єднання OUTER APPLY:

SELECT * FROM table1 AS t1 OUTER APPLY func1(t1.c2 + 1)

Результат виконання цієї команди буде наступним:

с1

с2

с3

с1

с2

с3

1

2

1

2

3

8

1

2

2

2

3

8

1

2

3

2

3

8

1

2

4

2

3

8

2

5

5

NULL

NULL

NULL

6

5

6

NULL

NULL

NULL

2

4

7

2

5

5

2

4

7

6

5

6

2

3

8

2

4

7

11

11

9

NULL

NULL

NULL

13

11

10

NULL

NULL

NULL

10

10

11

11

11

9

10

10

11

13

11

10

Приклад 5.

Оператори PIVOT і UNPIVOT.

Розглянемо використання оператора PIVOT на наступному прикладі: нехай, необхідно написати таку команду SELECT, що для таблиці table1 поверне один рядок значень, що для діапазону значень стовпця c1 від 1 до 13 буде містити середнє (округлене) значення по стовпцю c2 для кожного присутнього в таблиці значення стовпця c1. NULL - у випадку, коли такого значення стовпця c1 у таблиці table1 немає.

SELECT 'AverC2' as C1_VAL, [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13]

FROM (SELECT c1, c2 FROM table1) as t1

PIVOT( avg(c2) FOR c1

IN([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13])) as tt1

Результати роботи команди:

C1_VAL

1

2

3

4

5

6

7

8

9

10

11

12

13

AverC2

2

4

NULL

NULL

NULL

5

NULL

NULL

NULL

10

11

NULL

11

Якщо цю множину рядків потрібно було б відразу записати в таблицю, то це можна було б зробити за допомогою такої команди SELECT:

SELECT * INTO PVT FROM

(

SELECT 'AverC2' as C1_VAL, [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13]

FROM (SELECT c1, c2 FROM table1) as t1

PIVOT( avg(c2) FOR c1

IN([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13])) as tt1

) as tt2

Для демонстрації можливостей оператора UNPIVOT для таблиці PVT одержимо традиційну (у вигляді набору рядків) розбивки на групи, що не має значень NULL. Цього можна досягти наступною командою SELECT:

SELECT c1, c2 from (SELECT * FROM pvt) as t1

UNPIVOT( c2 FOR c1

IN([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13])) as tt1

у результаті виконання якої буде отримана наступна множин рядків:

с1

с2

1

2

2

4

6

5

10

10

11

11

13

11

Приклад 6.

Використання секцій WHERE, GROUP BY і HAVING.

Розглянемо приклад найпростішої команди SELECT, що формує групи на підставі стовпця c1, причому для кожної групи формується середнє значення по полю c2:

SELECT c1, avg(c2) as AVG_C2 FROM table1 WHERE c1 <> 2 GROUP BY ALL c1

Результат виконання команди:

c1

AVG_C2

1

2

2

NULL

6

5

10

10

11

11

13

11

Оскільки використана опція ALL, то з'являється рядок зі значеннями (2, NULL), що відсівається секцією WHERE. Однак, якщо модифікувати комнаду, додавши в неї таку секцію HAVING:

SELECT c1, avg(c2) as AVG_C2 FROM table1 WHERE c1 <> 2 GROUP BY ALL c1

HAVING c1 <> 2

то рядок (2, NULL) пропаде з результуючої множини.

Розглянемо приклад використання опції WITH CUBE:

SELECT c1, c2 FROM table1 GROUP BY c1, c2 WITH CUBE

Результат виконання команди буде наступним:

c1

c2

1

2

1

NULL

2

3

2

4

2

5

2

NULL

6

5

6

NULL

10

10

10

NULL

11

11

11

NULL

13

11

13

NULL

NULL

NULL

NULL

2

NULL

3

NULL

4

NULL

5

NULL

10

NULL

11

Тепер розглянемо приклад використання оператора GROUP BY c опцією WITH ROLLUP:

SELECT c1, c2 FROM table1 GROUP BY c1, c2 WITH ROLLUP

Результат виконання команди буде наступним:

c1

c2

1

2

1

NULL

2

3

2

4

2

5

2

NULL

6

5

6

NULL

10

10

10

NULL

11

11

11

NULL

13

11

13

NULL

NULL

NULL

Приклад 7.

Горизонтальні об'єднання.

UNION:

SELECT * FROM table1 WHERE c2 <=2

UNION

SELECT * FROM table2 WHERE c2 > 3

Результат:

с1

с2

с3

1

2

1

1

2

2

1

2

3

1

2

4

1

4

2

1

5

3

2

4

7

2

13

8

3

6

5

6

5

6

EXCEPT:

SELECT * FROM table1 WHERE c2 = 2

EXCEPT

SELECT * FROM table2 WHERE c2 = 2

Результат:

с1

с2

с3

1

2

2

1

2

3

INTERSECT:

SELECT * FROM table1 WHERE c2 = 2