Базы данных. Лекция 9. Несколько SELECT`ов в одном запросе

advertisement
БАЗЫ ДАННЫХ
НЕСКОЛЬКО SELECT’ов
В ОДНОМ ПРЕДЛОЖЕНИИ
1
ПОДЗАПРОСЫ ИЛИ
ВЛОЖЕННЫЙ SELECT
Geography
Store_Information
store_name
Sales
Los Angeles
San Diego
Los Angeles
$1500 Jan-05-1999
$250 Jan-07-1999
$300 Jan-08-1999
Boston
Date
$700 Jan-08-1999
region_name store_name
East
East
West
West
SELECT SUM(Sales) FROM Store_Information
WHERE Store_name IN
(SELECT store_name FROM Geography
WHERE region_name = 'West');
Boston
New York
Los Angeles
San Diego
SUM(Sales)
2050
2
ПОДЗАПРОСЫ ИЛИ
ВЛОЖЕННЫЙ SELECT
SELECT "column_name1"
FROM "table_name"
WHERE "column_name2" [Оператор сравнения]
(SELECT "column_name1"
FROM "table_name"
WHERE [Условия]);
Результат
подзапроса
должен
содержать
ЕДИНСТВЕННО
Е значение
3
КВАНТОР СУЩЕСТВОВАНИЯ
ОПЕРАТОР EXISTS
SELECT columns
FROM tables
WHERE EXISTS (subquery);
Выражение считается истинным только тогда,
когда результат вычисления subquery является
непустым множеством, т.е. когда существует какая-либо
запись в таблице, указанной во фразе FROM подзапроса,
которая удовлетворяет условию WHERE подзапроса.
4
ОПЕРАТОР EXISTS
Определить список имеющихся на складе товаров
SELECT Название FROM Товар
WHERE EXISTS (SELECT КодТовара FROM Склад
WHERE Товар.КодТовара=Склад.КодТовара)
Ключевые слова EXISTS и NOT EXISTS предназначены для
использования только совместно с подзапросами. Результат их обработки
представляет собой логическое значение TRUE или FALSE. Для ключевого
слова EXISTS результат равен TRUE в том и только в том случае, если в
возвращаемой подзапросом результирующей таблице присутствует хотя бы
одна строка. Если результирующая таблица подзапроса пуста, результатом
обработки операции EXISTS будет значение FALSE. Для ключевого слова NOT
EXISTS используются правила обработки, обратные по отношению к
ключевому слову EXISTS. Поскольку по ключевым словам EXISTS и NOT
EXISTS проверяется лишь наличие строк в результирующей таблице
подзапроса, то эта таблица может содержать произвольное количество
столбцов.
5
ОПЕРАТОР EXISTS
Определить список отсутствующих на складе товаров
SELECT Название FROM Товар WHERE NOT EXISTS
(SELECT КодТовара FROM Склад
WHERE Товар.КодТовара=Склад.КодТовара);
Ключевые слова EXISTS и NOT EXISTS предназначены для
использования только совместно с подзапросами. Результат их обработки
представляет собой логическое значение TRUE или FALSE. Для ключевого
слова EXISTS результат равен TRUE в том и только в том случае, если в
возвращаемой подзапросом результирующей таблице присутствует хотя бы
одна строка. Если результирующая таблица подзапроса пуста, результатом
обработки операции EXISTS будет значение FALSE. Для ключевого слова NOT
EXISTS используются правила обработки, обратные по отношению к
ключевому слову EXISTS. Поскольку по ключевым словам EXISTS и NOT
EXISTS проверяется лишь наличие строк в результирующей таблице
подзапроса, то эта таблица может содержать произвольное количество
6
столбцов.
ОПЕРАТОР EXISTS
EXISTS uses a subquery as a condition, where the condition is True if the
subquery returns any rows, and False if the subquery does not
return any rows; this is a nonintuitive feature with few unique
uses. However, if a prospective customer wanted to see the list of
Owners only if the shop dealt in Chairs, try использует подвопрос
SELECT OWNERFIRSTNAME, OWNERLASTNAME FROM ANTIQUEOWNERS
WHERE EXISTS
(SELECT * FROM ANTIQUES WHERE ITEM = 'Chair');
If there are any Chairs in the Antiques column, the subquery would return
a row or rows, making the EXISTS clause true, causing SQL to list the
Antique Owners. If there had been no Chairs, no rows would have been
returned by the outside query.
7
ОПЕРАТОР EXISTS
ALL is another unusual feature, as ALL queries can usually be done with
different, and possibly simpler methods; let's take a look at an example
query:
SELECT BUYERID, ITEM FROM ANTIQUES
WHERE PRICE >= ALL (SELECT PRICE FROM ANTIQUES);
This will return the largest priced item (or more than one item if there is a
tie), and its buyer. The subquery returns a list of all Prices in the Antiques
table, and the outer query goes through each row of the Antiques table,
and if its Price is greater than or equal to every (or ALL) Prices in the list, it
is listed, giving the highest priced Item. The reason ">=" must be used is
that the highest priced item will be equal to the highest price on the list,
because this Item is in the Price list.
8
ОБЪЕДИНЕНИЕ ЗАПРОСОВ
UNION
[SQL Statement 1]
UNION
[SQL Statement 2]
9
ОБЪЕДИНЕНИЕ ЗАПРОСОВ
UNION
Store_Information
store_name
Sales
Date
Los Angeles
$1500
Jan-05-1999
San Diego
$250
Jan-07-1999
Los Angeles
$300
Jan-08-1999
Boston
$700
Jan-08-1999
SELECT Date FROM Store_Information
UNION
SELECT Date FROM Internet_Sales;
Date
Internet Sales
Jan-05-1999
Date
Sales
Jan-07-1999
$250
Jan-10-1999
$535
Jan-11-1999
$320
Jan-10-1999
Jan-12-1999
$750
Jan-11-1999
Jan-07-1999
Jan-08-1999
Jan-12-1999
10
ОБЪЕДИНЕНИЕ ЗАПРОСОВ
UNION
[SQL Statement 1]
UNION ALL
[SQL Statement 2]
11
ОБЪЕДИНЕНИЕ ЗАПРОСОВ
UNION
Store_Information
store_name
Sales
Date
Los Angeles
$1500
Jan-05-1999
San Diego
$250
Jan-07-1999
Los Angeles
$300
Jan-08-1999
Boston
$700
Jan-08-1999
Internet Sales
SELECT Date FROM Store_Information
UNION ALL
SELECT Date FROM Internet_Sales ;
Date
Date
Jan-05-1999
Jan-05-1999
Jan-07-1999
Jan-07-1999
Date
Sales
Jan-08-1999
Jan-08-1999
Jan-07-1999
$250
Jan-08-1999
Jan-10-1999
Jan-10-1999
$535
Jan-07-1999
Jan-11-1999
Jan-11-1999
$320
Jan-10-1999
Jan-12-1999
Jan-12-1999
$750
Jan-11-1999
Jan-12-1999
12
ОБЪЕДИНЕНИЕ ЗАПРОСОВ
INTERSECT
[SQL Statement 1]
INTERSECT
[SQL Statement 2]
13
ОБЪЕДИНЕНИЕ ЗАПРОСОВ
UNION
Store_Information
store_name
Sales
Date
Los Angeles $1500
Jan-05-1999
San Diego
$250
Jan-07-1999
Los Angeles $300
Jan-08-1999
Boston
Jan-08-1999
$700
SELECT Date FROM Store_Information
INTERSECT
SELECT Date FROM Internet_Sales ;
Date
Internet Sales
Date
Sales
Jan-07-1999
$250
Jan-10-1999
$535
Jan-11-1999
$320
Jan-12-1999
$750
Jan-07-1999
14
ОБЪЕДИНЕНИЕ ЗАПРОСОВ
MINUS
[SQL Statement 1]
MINUS
[SQL Statement 2]
15
ОБЪЕДИНЕНИЕ ЗАПРОСОВ
MINUS
Store_Information
store_name
Sales
Date
Los Angeles
$1500
Jan-05-1999
San Diego
$250
Jan-07-1999
Los Angeles
$300
Jan-08-1999
Boston
$700
Jan-08-1999
Internet Sales
Date
Sales
Jan-07-1999
$250
Jan-10-1999
$535
Jan-11-1999
$320
Jan-12-1999
$750
SELECT Date FROM Store_Information
MINUS
SELECT Date FROM Internet_Sales ;
Date
Jan-05-1999
Jan-08-1999
16
СОЕДИНЕНИЕ - JOIN
Employees
Employee_ID
Orders
Name
Prod_ID Product Employee_ID
01
Hansen, Ola
234
Printer
01
02
Svendson, Tove
657
Table
03
03
Svendson, Stephen
865
Chair
03
04
Pettersen, Kari
Name
Hansen, Ola
Product
Printer
Svendson, Stephen Table
Svendson, Stephen Chair
SELECT Employees.Name, Orders.Product
FROM Employees, Orders
WHERE Employees.Employee_ID=Orders.Employee_ID;
17
СОЕДИНЕНИЕ - JOIN
Employees
Employee_ID
Orders
Name
Prod_ID Product Employee_ID
01
Hansen, Ola
234
Printer
01
02
Svendson, Tove
657
Table
03
03
Svendson, Stephen
865
Chair
03
04
Pettersen, Kari
Name
Hansen, Ola
SELECT Employees.Name FROM Employees, Orders
WHERE Employees.Employee_ID=Orders.Employee_ID AND
Orders.Product='Printer' ;
КТО КУПИЛ ПРИНТЕР?
18
ЯВНОЕ СОЕДИНЕНИЕ – INNER JOIN
SELECT field1, field2, field3 FROM first_table
INNER JOIN second_table
ON first_table.keyfield = second_table.foreign_keyfield
19
ЯВНОЕ СОЕДИНЕНИЕ – INNER JOIN
Employees
Employee_ID
Orders
Name
Prod_ID Product Employee_ID
01
Hansen, Ola
234
Printer
01
02
Svendson, Tove
657
Table
03
03
Svendson, Stephen
865
Chair
03
04
Pettersen, Kari
Name
Hansen, Ola
Product
Printer
Svendson, Stephen Table
Svendson, Stephen Chair
SELECT Employees.Name, Orders.Product FROM Employees
INNER JOIN Orders ON
Employees.Employee_ID=Orders.Employee_ID ;
20
СОЕДИНЕНИЕ СЛЕВА – LEFT JOIN
SELECT field1, field2, field3 FROM first_table
LEFT JOIN second_table
ON first_table.keyfield = second_table.foreign_keyfield
21
СОЕДИНЕНИЕ СЛЕВА – LEFT JOIN
Employees
Employee_ID
Orders
Name
Prod_ID Product Employee_ID
01
Hansen, Ola
234
02
Svendson, Tove
657
Table
Product
865
Chair
Printer
03
04
Name
Svendson, Stephen
Hansen, Ola
Pettersen, Kari
Svendson, Tove
Printer
01
03
03
Svendson, Stephen Table
Svendson, Stephen Chair
Pettersen, Kari
SELECT Employees.Name, Orders.Product FROM Employees
LEFT JOIN Orders
ON Employees.Employee_ID=Orders.Employee_ID ;
22
СОЕДИНЕНИЕ СПРАВА – RIGHT JOIN
SELECT field1, field2, field3 FROM first_table
RIGHT JOIN second_table
ON first_table.keyfield = second_table.foreign_keyfield
23
СОЕДИНЕНИЕ СПРАВА – LEFT JOIN
Employees
Employee_ID
Orders
Name
Prod_ID Product Employee_ID
01
Hansen, Ola
234
Printer
01
02
Svendson, Tove
657
Table
03
03
Svendson, Stephen
865
Chair
03
04
Pettersen, Kari
Name
Hansen, Ola
Product
Printer
Svendson, Stephen Table
Svendson, Stephen Chair
SELECT Employees.Name, Orders.Product FROM Employees
RIGHT JOIN Orders
ON Employees.Employee_ID=Orders.Employee_ID ;
24
СОЕДИНЕНИЕ СПРАВА – LEFT JOIN
Employees
Employee_ID
Orders
Name
Prod_ID Product Employee_ID
01
Hansen, Ola
234
Printer
01
02
Svendson, Tove
657
Table
03
03
Svendson, Stephen
865
Chair
03
04
Pettersen, Kari
Name
КТО КУПИЛ ПРИНТЕР?
Hansen, Ola
SELECT Employees.Name FROM Employees
INNER JOIN Orders
ON Employees.Employee_ID=Orders.Employee_ID
WHERE Orders.Product = 'Printer' ;
25
ГРУППИРОВАНИЕ - GROUP BY
SELECT column, SUM(column)
FROM table
GROUP BY column
26
ГРУППИРОВАНИЕ - GROUP BY
Sales
Company
Amount
W3Schools 5500
IBM
4500
W3Schools 7100
SELECT Company, SUM(Amount) FROM Sales;
Company
SUM(Amount)
W3Schools 17100
IBM
17100
W3Schools 17100
SELECT Company,SUM(Amount) FROM Sales
GROUP BY Company;
Company
SUM(Amount)
W3Schools 12600
IBM
4500
27
ГРУППИРОВАНИЕ - GROUP BY… HAVING...
SELECT column,SUM(column) FROM table
GROUP BY column
HAVING SUM(column) condition value
28
ГРУППИРОВАНИЕ - GROUP BY… HAVING...
Sales
Company
Amount
W3Schools 5500
IBM
4500
W3Schools 7100
SELECT Company,SUM(Amount) FROM Sales
GROUP BY Company
HAVING SUM(Amount)>10000;
Company
SUM(Amount)
W3Schools 12600
29
ПРЕДЛОЖЕНИЕ SELECT INTO
SELECT column_name(s)
INTO newtable [IN externaldatabase]
FROM source
30
ПРЕДЛОЖЕНИЕ SELECT INTO
SELECT * INTO Persons_backup FROM Persons
SELECT Persons.* INTO Persons IN 'Backup.mdb' FROM Persons
SELECT LastName,FirstName INTO Persons_backup FROM Persons
SELECT LastName,Firstname INTO Persons_backup FROM Persons
WHERE City='Sandnes'
SELECT Employees.Name,Orders.Product INTO Empl_Ord_backup
FROM Employees
INNER JOIN Orders
ON Employees.Employee_ID=Orders.Employee_ID
31
ПРЕДСТАВЛЕНИЯ
ПРЕДЛОЖЕНИЕ CREATE VIEW
CREATE VIEW view_name AS
SELECT column_name(s) FROM table_name
WHERE condition
32
ПРЕДСТАВЛЕНИЯ
ПРЕДЛОЖЕНИЕ CREATE VIEW
CREATE VIEW [Current Product List] AS
SELECT ProductID,ProductName FROM Products
WHERE Discontinued=No;
CREATE VIEW [Products Above Average Price] AS
SELECT ProductName,UnitPrice FROM Products
WHERE UnitPrice>(SELECT AVG(UnitPrice) FROM Products);
CREATE VIEW [Category Sales For 1997] AS
SELECT DISTINCT CategoryName,Sum(ProductSales)
AS CategorySales
FROM [Product Sales for 1997]
GROUP BY CategoryName;
SELECT * FROM [Category Sales For 1997]
WHERE CategoryName='Beverages';
33
БЕЗОПАСНОСТЬ И САНКЦИОНИРОВАНИЕ ДОСТУПА
ПРЕДЛОЖЕНИЯ GRANT и REVOKE
GRANT {привилегии}
ON {объекты}
TO {пользователи} [ WITH ADMIN OPTION]
Привилегии для таблиц и представлений:
SELECT
UPDATE (может относиться к конкретным столбцам)
DELETE
INSERT
ALL PRIVILEGES – все привилегии
Только для базовых таблиц:
ALTER
INDEX
34
БЕЗОПАСНОСТЬ И САНКЦИОНИРОВАНИЕ ДОСТУПА
ПРЕДЛОЖЕНИЯ GRANT и REVOKE
GRANT SELECT ON TABLE S TO U1805;
GRANT SELECT, UPDATE (CITY, PERSON)
ON TABLE S TO U1805, Mary, Bob;
GRANT ALL PRIVELEGES ON TABLE S, P, SP TO Boss;
GRANT SELECT ON TABLE P TO PUBLIC;
Специальное ключевое
слово означающее
общедоступный
35
БЕЗОПАСНОСТЬ И САНКЦИОНИРОВАНИЕ ДОСТУПА
ПРЕДЛОЖЕНИЯ GRANT и REVOKE
REVOKE {привилегии} [ON объекты] FROM {пользователи}
REVOKE SELECT ON TABLE S FROM U1805;
Отмена привилегии UPDATE не может
относиться к конкретным столбцам
36
i12
УТРАТА ОБНОВЛЕНИЯ И
УСТАНОВКА БЛОКИРОВКИ
результат обновления
утрачен
i12
i11
i12
редактирование
I
u1, c1
t11 i11
t
2
1
i
se
u2, c2
t13
1
2
se
t
1
2
t
i22
t14
sw
i 21
2
2
i12
i22
редактирование
i21  i11
i11
sw
t
t 24
3
2
i12
редактирование
u1, c1
t12 Блокировка LI
t11
se
t14 Блокировка LI снята
i12
i11
I
t13
t 21
se
sw
t 22
u2, c2
i22
i 21
t 23
se
i21  i12
t 25 s w
t 24
i 21
ожидание
Отказ в доступе
t 26
i22
редактирование
Блокировка L2
Блокировка L2 снята
37
БЕСКОНЕЧНОЕ ОТКЛАДЫВАНИЕ И ПРИОРИТЕТНЫЙ
ПОЛЬЗОВАТЕЛЬ
i11
i11
i12
редактирование
редактирование
u1, c1
t
1
1
t
2
1
t13
Блокировка LI
t 21
se
sse
e
t 22
t12 Блокировка L2
t11
i11
i12
i11
I
t14 Блокировка LI снята
sw
se
se
t 21
t 22
u2, c2
ожидание
ожидание
Отказ в доступе
Отказ в доступе
i12
i11
редактирование
I
u1, c1
u2, c2
t
1
1
1
1
i
se
t
2
1
i
t 21 s e t 22
i21  i11
t13
i22
1
2
i 21
i22
редактирование
t14
sw
sw
t 23
i12
t 24
38
ТРАНЗАКЦИИ
COMMIT и ROLLBACK
START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summmary=@A WHERE type=1;
IF «всё завершилось хорошо» THEN
COMMIT; -- «утвердить» изменения
ELSE
ROLLBACK; -- восстановить состояние до начала транзакции
END IF;
39
ТРАНЗАКЦИИ
COMMIT и ROLLBACK
LOCK TABLES tbl_name [AS alias]
{READ [LOCAL] | [LOW_PRIORITY] WRITE}
[, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES
Команда LOCK TABLES блокирует указанные в ней таблицы для
данного потока. Команда UNLOCK TABLES снимает любые блокировки,
удерживаемые данным потоком. Все таблицы, заблокированные
текущим потоком, автоматически разблокируются при появлении в
потоке иной команды LOCK TABLES или при прекращении соединения
с сервером.
40
КУРСОРЫ
ВЕРСИЯ ORACLE
Завершить
цикл если
курсор пуст
LOOP
DECLARE
CURSOR c_american_pie IS
SELECT Film_Title FROM Film_Table
WHERE Film_Title like "American Pie%";
OPEN c_american_pie;
FETCH c_american_pie INTO v_film_title;
EXIT WHEN c_american_pie%NOT_FOUND;
-- Обрабатываем полученные данные.
-- В этом примере просто наращивается счётчик,
-- Хотя что-то можно сделать с значением переменной v_film_title
v_american_pie_count := v_american_pie_count + 1;
END LOOP;
CLOSE c_american_pie;
41
КУРСОРЫ
ВЕРСИЯ DB2
Declare MyCursor Cursor for
Select Film_Title From Director_Film_Table,
Where Director_Last_Name equals "Cameron" and
Director_First_Name equals "James" Order By Film_Title;
Open MyCursor;
LOOP
SQLCODE is set to +100
Fetch MyCursor Into : CameronMovieName;
END LOOP;
Close MyCursor;
42
VBS & RECORDSET
Pth= "путь к файлу .mdb"
Set oConn = CreateObject("ADODB.Connection")
oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Pth
sSQL = "SELECT…;"
Set oRs = oConn.Execute(sSQL)
If oRs.eof then
' WScript.Echo(oRs("STAT0"))
Else
CodeMax = oRs("STAT0")
End If
oRs.Close
oConn.Close
set oRs = nothing
set oConn = nothing
43
КАК УБРАТЬ ОДИНАКОВЫЕ СТРОКИ
ПЕРВЫЙ СПОСОБ
select * from foo;
----------------------------------| first_name | last_name |
----------------------------------| Donald
| Duck
|
| Mighty
| Mouse
|
| Donald
| Duck
|
----------------------------------3 rows selected
select distinct into {временная таблица}
44
КАК УБРАТЬ ОДИНАКОВЫЕ СТРОКИ
ВТОРОЙ СПОСОБ
select * from foo;
----------------------------------| first_name | last_name |
----------------------------------| Donald
| Duck
|
| Mighty
| Mouse
|
| Donald
| Duck
|
----------------------------------3 rows selected
-------------------------------------------| oid | first_name | last_name |
-------------------------------------------| 2001 | Donald
| Duck
|
| 2002 | Mighty
| Mouse
|
| 2003 | Donald
| Duck
|
-------------------------------------------3 rows selected
45
Download