sql grouping, joins
TRANSCRIPT
eleks.com eleks.com
ГрупуванняОперації над множинами
• Групування• З’єднання• Декартів добуток• Переріз• Різниця
Групування результату (GROUP BY):select Name, sum(Amount) as [sum] from Client GROUP BY Name
Name sum--------- --------Client_1 0.00Client_2 20.00Client_3 -10.00
Group by
•Якщо не отримано жодної стрічки, то результатом виконання функції COUNT буде нуль, а результатом всіх інших функцій - NULL.
•Аргумент агрегатної функції не може сам вміщати агрегатні функції (функція від функції). Тобто, наприклад, в одному запиті не можна отримати максимум середніх значень.
•Результат виконання функції COUNT - ціле число (INT), інші агрегатні функції наслідують типи даних оброблювальних значень
•Якщо при використанні функції SUM був отриманий результат, що перевищує максимальне значення даного типу даних, то виникає помилка
AVG – середнє значення стовпчика (тільки числові типи)COUNT – кількість стрічок (значень заданого поля)COUNT_BIG – аналогічно до COUNT для типу bigintMAX – найбільше значенняMIN – найменше значенняSUM – сума всіх значень (тільки числові типи)GROUPING – тип стрічки при використання ROLE або CUBE
Агрегуючі функції
COUNT(*) повертає кількість всіх стрічок по заданій умові, не зважаючи на NULLCOUNT(<назва поля>) обчислює кількість не NULL значень у заданій колонціCOUNT(DISTINCT <назва поля>) підраховує кількість унікальних не NULL значеньselect count(*), count(Comment), count(distinct Comment),
max(Name), min(Address), avg(Amount), sum(Amount)
from Client
cnt cnt_c cnt_d max min avg sum---- ----- ----- -------- ---------- ------- ------3 2 2 Client_3 Address_1 3.3333 10.00
Агрегуючі функції
Використання підсумкових значень (ROLLUP,CUBE):select Name, sum(Amount) [sum] from Client group by Name with ROLLUP
Name sum---------- -------Client_1 0.00Client_2 20.00Client_3 -10.00NULL 10.00
Обмеження результату (HAVING)select Name, sum(Amount) [sum] from Clientgroup by NameHAVING sum(Amount) > 0
Name sum--------- -------Client_2 20.00
Агрегуючі функції
Традиційні операції над множинами: •З'єднання•Декартів добуток•Об'єднання•Переріз та різниця
select Document.Number, Document.Date, Client.Namefrom Client, Documentwhere Client.ClientId = Document.ClientIdNumber Date Name---------- ----------------------- ----------I-001 2007-01-04 00:00:00.000 Client_1I-002 2007-01-04 00:00:00.000 Client_2I-003 2007-02-04 00:00:00.000 Client_1I-004 2007-02-04 00:00:00.000 Client_1P-001 2007-01-04 00:00:00.000 Client_1P-002 2007-02-04 00:00:00.000 Client_1P-003 2007-02-04 00:00:00.000 Client_2
Операції над кількома множинами
Внутрішнє з'єднання (INNER JOIN):
select c.Name, d.Number, d.Datefrom Client c inner join Document d
on c.ClientId = d.ClientId
З’єднання множинName Number Date --------- --------- ----------------------- Client_1 I-001 2007-01-04 00:00:00.000 Client_1 I-003 2007-02-04 00:00:00.000 Client_1 I-004 2007-02-04 00:00:00.000 Client_1 P-001 2007-01-04 00:00:00.000 Client_1 P-002 2007-02-04 00:00:00.000
Зовнішнє з'єднання (OUTER, Left):select c.Name, d.Number, d.Date
from Client c left join Document don c.ClientId = d.ClientIdand month(d.Date) = 1and d.Number like 'I%‘
Name Number Date---------- ---------- ----------Client_1 I-001 2007-01-04Client_2 I-002 2007-01-04Client_3 NULL NULL
select c.Name, d.Number, d.Datefrom Client cleft join Document don c.ClientId = d.ClientIdand month(d.Date) = 1where d.Number like 'I%‘
Name Number Date--------- ---------- ----------Client_1 I-001 2007-01-04Client_2 I-002 2007-01-04
З’єднання множин
Симетричність операцій LEFT та RIGHTselect Name, Number, Date
from Documentright join Client
on Instance = Client
Повне з’єднання (FULL JOIN):select Name, Number, Date
from Document dfull join (select * from Client
where ClientId > 1) con c.ClientId = d.ClientId
Name Number Date----------- ---------- -----------------------NULL I-003 2007-02-04 00:00:00.000NULL I-004 2007-02-04 00:00:00.000NULL P-001 2007-01-04 00:00:00.000NULL P-002 2007-02-04 00:00:00.000NULL I-001 2007-01-04 00:00:00.000Client_2 I-002 2007-01-04 00:00:00.000Client_2 P-003 2007-02-04 00:00:00.000Client_3 NULL NULL
З’єднання множин
Повний перелік всіх рядків:select c.Name, dt.Namefrom Client ccross join DocumentType dt
Name Name---------- --------Client_1 InvoiceClient_2 InvoiceClient_3 InvoiceClient_1 PaymentClient_2 PaymentClient_3 Payment
Простий варіант запису:select c.Name, dt.Namefrom Client c, DocumentType dt
Декартів добуток
Об’єднання результатів запитів (UNION ALL):select 1 [ID], 'CLIENT_1' [Name]UNION ALLselect ClientId, Name from ClientID Name---- ----------1 CLIENT_11 Client_12 Client_23 Client_3
Унікальні рядки в результатах (UNION):select 1 [ID], 'CLIENT_1' [Name]UNIONselect ClientId, Name from ClientID Name---- ----------1 Client_12 Client_23 Client_3
Об’єднання множин
Об'єднання множинУмови об'єднання множин: Кількість вихідних стовпчиків кожного із запитів повинно бути
однаковим Вихідні колонки кожного підзапиту повинні бути порівняльними між
собою по типу даних (у відповідному порядку їх слідування). У результуючому наборі імена стовпців співпадають із заданими в
першому запиті Вираз ORDER BY застосовується до результату з’єднання і тому
вказується лише раз (в кінці запиту) За допомогою дужок можна міняти порядок виконання об’єднанняselect 0 [ID], 'ALL' [Name]UNION(select 1 [ID], 'CLIENT_1' [Name] UNION ALL select ClientId, Name
from Client)order by ID
ID Name---- ----------0 ALL1 CLIENT_12 Client_23 Client_3
Інші операції над множинами
INTERSECT
EXCEPT
Інші операції над множинамиОперація перетину множин (INTERSECT):
select 1 [ID], 'CLIENT_1' [Name]INTERSECTselect ClientId, Name from Client
ID Name---- ----------1 CLIENT_1
Операція різниці множин (EXCEPT):select ClientId, Name from ClientEXCEPTselect 1 [ID], 'CLIENT_1' [Name]
ID Name---- ----------2 Client_23 Client_3
Додаткові можливості оператора SELECTОпція FOR XML (AUTO, PATH, RAW):select c.ClientId, c.Name, c.Address,
d.DocumentId, d.Number, d.Datefrom Client c, Document dwhere c.ClientId = d.ClientIdfor xml auto, elements, root('Clients')
Оператори PIVOT та UNPIVOT:select [1] M1, [2] M2, [3] M3, [4] M4, [5] M5, [6] M6
from (select month(Date) nm, Amount from Document) dpivot (sum(Amount) for d.nm in ([1],[2],[3],[4],[5],[6])) dd
M1 M2 M3 M4 M5 M6------- ------- ------- ------- ------- -------55.00 90.00 NULL NULL NULL NULL