СУБД. Лекция 3

СУБД
Навроцкий Артем
Лекция 3

INSERT

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

Or:

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    SET col_name={expr | DEFAULT}, ...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

INSERT

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

INSERT

INSERT INTO tbl_temp2 (fld_id)
    SELECT 
        tbl_temp1.fld_order_id
    FROM 
        tbl_temp1 
    WHERE 
        tbl_temp1.fld_order_id > 100;
 
INSERT INTO table (a,b,c) VALUES (1,2,3) 
    ON DUPLICATE KEY UPDATE c=c+1;
 
INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) 
    ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

UPDATE

UPDATE [LOW_PRIORITY] [IGNORE] table_reference
    SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
    [WHERE where_condition]
    [ORDER BY ...]
    [LIMIT row_count]

Multiple-table syntax:

 
UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
    [WHERE where_condition]

DELETE

DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
    [WHERE where_condition]
    [ORDER BY ...]
    [LIMIT row_count]

Multiple-table syntax:

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    tbl_name[.*] [, tbl_name[.*]] ...
    FROM table_references
    [WHERE where_condition]

Or:

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    FROM tbl_name[.*] [, tbl_name[.*]] ...
    USING table_references
    [WHERE where_condition]

DELETE

DELETE
    t1, t2 
FROM 
    t1 INNER JOIN t2 
    INNER JOIN t3 
WHERE 
    t1.id=t2.id AND t2.id=t3.id;

Or:

DELETE FROM
    t1, t2 
USING 
    t1 INNER JOIN t2 
    INNER JOIN t3 
WHERE 
    t1.id=t2.id AND t2.id=t3.id;

Пользовательские переменные

SET @var_name = expr [, @var_name = expr] ...

SET @t1 = 1, @t2 = 2, @t3 := 4;
SELECT @t1, @t2, @t3, @t4 := @t1 + @t2 + @t3
@t1 @t2 @t3 @t4 := @t1 + @t2 + @t3
1 2 4 7
SET @i := 0;
SELECT @i := @i + 1 AS row_number, t.* FROM your_table AS t;
 
SELECT @i := @i + 1 AS row_number, t.*
FROM your_table AS t, (SELECT @i:=0) AS z;

SUBQUERIES


SELECT
    col0,
    (SELECT col1 FROM table1 WHERE table1.id = table0.id),
    (SELECT col2 FROM table1 WHERE table1.id = table0.id)
FROM
    table0;
non_subquery_operand comparison_operator (subquery)
=  >  <  >=  <=  <>  !=  LIKE
SELECT *
FROM t1
WHERE column1 = (SELECT MAX(column2) FROM t2);

SELECT *
FROM t1 AS t
WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);

SUBQUERIES

perand comparison_operator ANY (subquery)
operand IN (subquery) operand
comparison_operator SOME (subquery)
 
    SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);
 
    SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2);
    SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2);
 
operand comparison_operator ALL (subquery)
 
    SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);
 
    SELECT s1 FROM t1 WHERE s1 <> ALL (SELECT s1 FROM t2);
    SELECT s1 FROM t1 WHERE s1 NOT IN (SELECT s1 FROM t2);

ROW SUBQUERIES

SELECT *
FROM t1
WHERE (col1, col2)
	= (SELECT col3, col4 FROM t2 WHERE id = 10);
 
SELECT *
FROM t1
WHERE ROW (col1, col2)
	= (SELECT col3, col4 FROM t2 WHERE id = 10);

SELECT column1, column2, column3
FROM t1
WHERE (column1, column2, column3)
    IN (SELECT column1, column2, column3 FROM t2);

[NOT] EXISTS

SELECT DISTINCT store_type
FROM stores
WHERE EXISTS (
    SELECT *
    FROM cities_stores
    WHERE cities_stores.store_type = stores.store_type
);
 
SELECT DISTINCT store_type
FROM stores
WHERE NOT EXISTS (
    SELECT *
    FROM cities_stores
    WHERE cities_stores.store_type = stores.store_type
);

SUBQUERIES in FROM

SELECT ... FROM (subquery) [AS] name ...
 
SELECT AVG(sum_column1)
FROM (
    SELECT SUM(column1) AS sum_column1
    FROM t1
    GROUP BY column1
) AS t1;

UNION

SELECT ...
UNION [ALL | DISTINCT]
SELECT ...
[UNION [ALL | DISTINCT]
SELECT ...]
person amount
Joe 1000
Alex 2000
Bob 5000
person amount
Joe 2000
Alex 2000
Zach 35000
SELECT * FROM sales2010
UNION
SELECT * FROM sales2011;
person amount
Joe 1000
Joe 2000
Alex 2000
Bob 5000
Zach 35000
SELECT * FROM sales2010
UNION ALL
SELECT * FROM sales2011;
person amount
Joe 1000
Joe 2000
Alex 2000
Alex 2000
Bob 5000
Zach 35000

Набор данных

Employee
LastName DepartmentID
Rafferty 31
Jones 33
Steinberg 33
Robinson 34
Smith 34
John
Department
DepartmentID DepartmentName
31 Sales
33 Engineering
34 Clerical
35 Marketing

CROSS JOIN

SELECT * FROM Employee CROSS JOIN Department;
Employee.
LastName
Employee.
DepartmentID
Department.
DepartmentID
Department.
DepartmentName
Rafferty 31 31 Sales
Jones 33 31 Sales
Steinberg 33 31 Sales
Robinson 34 31 Sales
Smith 34 31 Sales
John 31 Sales
Rafferty 31 33 Engineering
Jones 33 33 Engineering
Steinberg 33 33 Engineering
Robinson 34 33 Engineering
Smith 34 33 Engineering
John 33 Engineering
Rafferty 31 34 Clerical
Jones 33 34 Clerical
Steinberg 33 34 Clerical
Robinson 34 34 Clerical
Smith 34 34 Clerical
John 34 Clerical
Rafferty 31 35 Marketing
Jones 33 35 Marketing
Steinberg 33 35 Marketing
Robinson 34 35 Marketing
Smith 34 35 Marketing
John 35 Marketing

CROSS JOIN

SELECT * FROM Employee, Department;
Employee.
LastName
Employee.
DepartmentID
Department.
DepartmentID
Department.
DepartmentName
Rafferty 31 31 Sales
Jones 33 31 Sales
Steinberg 33 31 Sales
Robinson 34 31 Sales
Smith 34 31 Sales
John 31 Sales
Rafferty 31 33 Engineering
Jones 33 33 Engineering
Steinberg 33 33 Engineering
Robinson 34 33 Engineering
Smith 34 33 Engineering
John 33 Engineering
Rafferty 31 34 Clerical
Jones 33 34 Clerical
Steinberg 33 34 Clerical
Robinson 34 34 Clerical
Smith 34 34 Clerical
John 34 Clerical
Rafferty 31 35 Marketing
Jones 33 35 Marketing
Steinberg 33 35 Marketing
Robinson 34 35 Marketing
Smith 34 35 Marketing
John 35 Marketing

INNER JOIN

SELECT *
FROM Employee
INNER JOIN Department
ON Employee.DepartmentID = Department.DepartmentID;
Employee.
LastName
Employee.
DepartmentID
Department.
DepartmentID
Department.
DepartmentName
Rafferty 31 31 Sales
Jones 33 33 Engineering
Steinberg 33 33 Engineering
Robinson 34 34 Clerical
Smith 34 34 Clerical

INNER JOIN

SELECT *
FROM Employee, Department
WHERE Employee.DepartmentID = Department.DepartmentID;

Employee.
LastName
Employee.
DepartmentID
Department.
DepartmentID
Department.
DepartmentName
Rafferty 31 31 Sales
Jones 33 33 Engineering
Steinberg 33 33 Engineering
Robinson 34 34 Clerical
Smith 34 34 Clerical

NATURAL (EQUAL) JOIN

SELECT *
FROM Employee
NATURAL JOIN Department;

DepartmentID Employee.
LastName
Department.
DepartmentName
31 Rafferty Sales
33 Jones Engineering
33 Steinberg Engineering
34 Robinson Clerical
34 Smith Clerical

NATURAL JOIN

SELECT *
FROM Employee
JOIN Department USING (DepartmentID);

DepartmentID Employee.
LastName
Department.
DepartmentName
31 Rafferty Sales
33 Jones Engineering
33 Steinberg Engineering
34 Robinson Clerical
34 Smith Clerical

LEFT OUTER JOIN

SELECT *
FROM Employee
LEFT OUTER JOIN Department
ON Employee.DepartmentID = Department.DepartmentID;
Employee.
LastName
Employee.
DepartmentID
Department.
DepartmentID
Department.
DepartmentName
Rafferty 31 31 Sales
Jones 33 33 Engineering
Steinberg 33 33 Engineering
John
Robinson 34 34 Clerical
Smith 34 34 Clerical

FULL OUTER JOIN

SELECT *
FROM Employee
FULL OUTER JOIN Department
ON Employee.DepartmentID = Department.DepartmentID;
Employee.
LastName
Employee.
DepartmentID
Department.
DepartmentID
Department.
DepartmentName
Rafferty 31 31 Sales
Jones 33 33 Engineering
Steinberg 33 33 Engineering
John
Robinson 34 34 Clerical
Smith 34 34 Clerical
35 Marketing

FULL OUTER JOIN

SELECT *
FROM Employee
FULL OUTER JOIN Department
ON Employee.DepartmentID = Department.DepartmentID;

SELECT *
FROM Employee
LEFT OUTER JOIN Department
ON Employee.DepartmentID = Department.DepartmentID;
 
UNION ALL
 
SELECT *
FROM Employee
RIGHT OUTER JOIN Department
ON Employee.DepartmentID = Department.DepartmentID
WHERE Employee.DepartmentID IS NULL;

SELF-JOIN

SELECT F.EmployeeID, F.LastName, S.EmployeeID, S.LastName, F.Country
FROM Employee F
INNER JOIN Employee S ON F.Country = S.Country
WHERE F.EmployeeID < S.EmployeeID
ORDER BY F.EmployeeID, S.EmployeeID;
EmployeeID LastName Country DepartmentID
123 Rafferty 31 Australia
124 Jones 33 Australia
145 Steinberg 33 Australia
201 Robinson 34 United States
305 Smith 34 Germany
306 John Germany

SELF-JOIN

EmployeeID LastName Country DepartmentID
123 Rafferty 31 Australia
124 Jones 33 Australia
145 Steinberg 33 Australia
201 Robinson 34 United States
305 Smith 34 Germany
306 John Germany
F.EmployeeID F.LastName S.EmployeeID S.LastName F.Country
123 Rafferty 124 Jones Australia
123 Rafferty 145 Steinberg Australia
124 Jones 145 Steinberg Australia
305 Smith 306 John Germany

SELF-JOIN

Представление (VIEW)
Объект базы данных, являющийся результатом выполнения запроса к базе данных, определенного с помощью оператора SELECT, в момент обращения к представлению.
CREATE
    [OR REPLACE]
    [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
    [DEFINER = { user | CURRENT_USER }]
    [SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name [(column_list)] AS select_statement
    [WITH [CASCADED | LOCAL] CHECK OPTION];

Преимущества VIEW

Ограничения VIEW

Особенности VIEW

CREATE VIEW v AS
    SELECT a.id, b.id FROM a,b;
-- Error Code: 1060. Duplicate column name 'id'

CREATE VIEW v (a_id, b_id) AS
    SELECT a.id, b.id FROM a,b;
CREATE VIEW v AS
    SELECT a.id a_id, b.id b_id FROM a,b;

CREATE VIEW v AS
    SELECT GROUP_CONCAT(
        DISTINCT column_name
        ORDER BY column_name separator '+'
    )
    FROM table_name;

Особенности VIEW

Алгоритмы VIEW (MERGE)

CREATE VIEW v AS
SELECT subject, num_views / num_replies AS param
FROM topics
WHERE num_replies > 0;

SELECT subject, param FROM v WHERE param > 1000;

SELECT subject, num_views / num_replies AS param
FROM topics
WHERE num_replies>0 AND num_views / num_replies > 1000;

Алгоритмы VIEW (TEMPTABLE)

CREATE VIEW v AS
SELECT forum_id, COUNT(*) AS num
FROM topics GROUP BY forum_id;

SELECT MAX(num) FROM v;

SELECT MAX(COUNT(*))
FROM topics GROUP BY forum_id;

CREATE TEMPORARY TABLE tmp_table
SELECT forum_id, COUNT(*) AS num
FROM topics GROUP BY forum_id;

SELECT MAX(num) FROM tmp_table;

DROP TABLE tmp_table;

Изменение VIEW

WITH [CASCADED | LOCAL] CHECK

Изменение VIEW

CREATE OR REPLACE VIEW v AS
    SELECT forum_name, subject, num_views
    FROM topics,forums f
    WHERE forum_id = f.id AND num_views > 2000
    WITH CHECK OPTION;


UPDATE v SET num_views = 1999 WHERE subject = 'test';
-- ERROR 1369 (HY000): CHECK OPTION failed 'test.v'

UPDATE v SET num_views = 2003 WHERE subject = 'test';
-- Query OK

Изменение VIEW

CREATE OR REPLACE VIEW v AS
    SELECT forum_name, subject, num_views
    FROM topics,forums f
    WHERE forum_id = f.id AND num_views > 2000
    WITH CHECK OPTION;


INSERT INTO v (subject, num_views)
VALUES ('test1', 4000);
-- ERROR 1369 (HY000): CHECK OPTION failed test.v

INSERT INTO v (forum_id, subject, num_views)
VALUES (1, 'test1', 4000);
-- ERROR 1054 (42S22): Unknown COLUMN 'forum_id' IN 'field list'
Навроцкий Артем
@gent: navrotskiy@corp.mail.ru
Спасибо за внимание!