-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathviews-modes.sql
More file actions
122 lines (92 loc) · 3.65 KB
/
views-modes.sql
File metadata and controls
122 lines (92 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
-- Views
-- Views are stored queries that wehn invoked produce a result set
-- A view acts as a virtual table.
USE reviews_app;
SELECT title, released_year, genre, rating, first_name, last_name
FROM reviews
JOIN series
ON series.id = reviews.series_id
JOIN reviewers
ON reviewers.id = reviews.reviewer_id;
CREATE VIEW full_reviews AS
SELECT title, released_year, genre, rating, first_name, last_name
FROM reviews
JOIN series
ON series.id = reviews.series_id
JOIN reviewers
ON reviewers.id = reviews.reviewer_id;
SHOW TABLES; -- full_reviews is here
SELECT * FROM full_reviews;
SELECT * FROM full_reviews
WHERE genre = 'Animation';
SELECT genre, AVG(rating) AS avg_rating
FROM full_reviews
GROUP BY genre;
-- Only small portion of views are updatable and insertable
-- full_reviews is not updatable
-- but this one is
CREATE VIEW ordered_series AS
SELECT * FROM series ORDER BY released_year;
SELECT * FROM ordered_series;
INSERT INTO ordered_series(title, released_year, genre)
VALUES ('The Great', 2020, 'Comedy'); -- ok
SELECT * FROM series; -- the row is also inserted into series
DELETE FROM ordered_series WHERE title = 'The Great'; -- ok
-- Altering/Replacing Views
CREATE OR REPLACE VIEW ordered_series AS
SELECT * FROM series ORDER BY released_year DESC;
SELECT * FROM ordered_series;
ALTER VIEW ordered_series AS
SELECT * FROM series ORDER BY released_year;
SELECT * FROM ordered_series;
-- Droping a view
DROP VIEW ordered_series; -- does not delete the data, only the view
-- HAVING - filtering groups
-- We want to select only these titles that have more than one review
SELECT title, AVG(rating) AS avg_rating FROM full_reviews
GROUP BY title HAVING COUNT(rating) > 1;
-- Select only these reviewers who avg_rating is more than 8
SELECT CONCAT(first_name, ' ', last_name) AS reviewer,
AVG(rating) AS avg_rating
FROM full_reviews
GROUP BY reviewer HAVING avg_rating > 8;
-- WITH ROLLUP
SELECT title, AVG(rating) FROM full_reviews
GROUP BY title WITH ROLLUP;
-- at the end of the result table we have
-- NULL - 8.02553 - it is the average rating for the whole table
SELECT title, COUNT(rating) FROM full_reviews
GROUP BY title WITH ROLLUP; -- in the last row we have count of all ratings
-- if we group by two things we get two level statistics
-- we get an average for each released_year
-- and at the end we get an average for all ratings
SELECT released_year, genre, AVG(rating) AS avg_rating
FROM full_reviews
GROUP BY released_year, genre WITH ROLLUP;
-- MODES
-- Setting that we can turn on/off to change the behavior and the validations of MySQL
-- Viewing Modes
SELECT @@GLOBAL.sql_mode; -- global settings
SELECT @@SESSION.sql_mode; -- for the current session
-- SET GLOBAL sql_mode = 'modes'; -- global modes
-- SET SESSION sql_mode = 'modes';
SELECT 3/0;
SHOW WARNINGS; -- warning by default
-- we disable ERROR_FOR_DIVISION_BY_ZERO
SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION';
SELECT 3/0;
SHOW WARNINGS; -- no warning now
-- STRICT_TRANS_TABLES - enabled by default
-- Strict mode controls how MySQL handles invalid or missing values in data-change statements
-- such as INSERT or UPDATE
-- If we disable strict mode, then when we try to insert a string to a numeric column
-- we will get only a warning and 0 is set as the value
-- ONLY_FULL_GROUP_BY
-- it allows to only select columns that are used in GROUP BY statement
-- or in aggregate function
SELECT title, AVG(rating) FROM series
JOIN reviews ON reviews.series_id = series.id
GROUP BY title;
-- NO_ZERO_IN_DATE, NO_ZERO_DATE
-- we can't use e.g. '2010-00-01', '2010-10-00', '0000-00-00'
-- mysql -u root -p -- to log in from terminal