-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path24_Expressions.sql
More file actions
236 lines (211 loc) · 6.84 KB
/
24_Expressions.sql
File metadata and controls
236 lines (211 loc) · 6.84 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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/**************************************************************
* MySQL 8.0 Expressions Tutorial
* This script demonstrates common MySQL expression
* types, including:
* - CASE expressions (simple and searched) for
* conditional logic and data categorization.
* - COALESCE to handle NULL values and provide defaults.
* - NULLIF to avoid divide-by-zero and suppress
* sentinel values.
* - IFNULL and IF as MySQL shorthand alternatives.
* - OUTPUT-equivalent pattern using LAST_INSERT_ID.
* - AT TIME ZONE equivalent via CONVERT_TZ.
* - Optimizer hints with SELECT statement hints.
**************************************************************/
-------------------------------------------------
-- Region: 0. Initialization
-------------------------------------------------
USE mysql_course;
DROP TABLE IF EXISTS sample_data;
CREATE TABLE sample_data
(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
age INT NOT NULL,
salary DECIMAL(10,2),
department VARCHAR(100) NOT NULL,
notes TEXT
) ENGINE = InnoDB;
INSERT INTO sample_data (name, age, salary, department, notes)
VALUES
('Alice', 30, 60000.00, 'HR', 'Initial note for Alice'),
('Bob', 25, NULL, 'IT', 'Initial note for Bob'),
('Charlie', 35, 80000.00, 'Finance', 'Initial note for Charlie'),
('David', 40, 90000.00, 'IT', 'Initial note for David'),
('Eve', 28, NULL, 'HR', 'Initial note for Eve');
-------------------------------------------------
-- Region: 1. Searched CASE Expression
-------------------------------------------------
/*
1.1 Classify employees into age groups.
*/
SELECT
name,
age,
CASE
WHEN age < 30 THEN 'Young'
WHEN age BETWEEN 30 AND 39 THEN 'Adult'
ELSE 'Senior'
END AS age_group
FROM sample_data;
/*
1.2 Handle NULL salary with a searched CASE.
*/
SELECT
name,
salary,
CASE
WHEN salary IS NULL THEN 'Salary not provided'
ELSE 'Salary provided'
END AS salary_status
FROM sample_data;
-------------------------------------------------
-- Region: 2. Simple CASE Expression
-------------------------------------------------
/*
2.1 Map department codes to descriptive labels.
*/
SELECT
name,
department,
CASE department
WHEN 'IT' THEN 'Information Technology'
WHEN 'HR' THEN 'Human Resources'
WHEN 'Finance' THEN 'Finance & Accounting'
ELSE 'Other'
END AS department_full
FROM sample_data;
-------------------------------------------------
-- Region: 3. COALESCE
-------------------------------------------------
/*
3.1 Return the first non-NULL value from a list.
Here salary defaults to 0 when not set.
*/
SELECT
name,
COALESCE(salary, 0.00) AS effective_salary
FROM sample_data;
/*
3.2 Concatenate optional fields, skipping NULLs.
*/
SELECT
name,
COALESCE(
CONCAT(department, ' – salary: ', salary),
CONCAT(department, ' – salary: not provided')
) AS summary
FROM sample_data;
-------------------------------------------------
-- Region: 4. NULLIF
-------------------------------------------------
/*
4.1 NULLIF(a, b) returns NULL when a = b.
Classic use: prevent division by zero.
*/
DROP TABLE IF EXISTS sales_data;
CREATE TABLE sales_data
(
product VARCHAR(100) NOT NULL,
units_sold INT NOT NULL DEFAULT 0,
revenue DECIMAL(10,2) NOT NULL DEFAULT 0
) ENGINE = InnoDB;
INSERT INTO sales_data (product, units_sold, revenue)
VALUES
('Widget A', 100, 5000.00),
('Widget B', 0, 0.00),
('Widget C', 50, 2500.00);
SELECT
product,
units_sold,
revenue,
revenue / NULLIF(units_sold, 0) AS avg_price_per_unit
FROM sales_data;
/*
4.2 Suppress a sentinel string and treat it as NULL.
*/
SELECT
name,
NULLIF(department, 'Finance') AS dept_no_finance
FROM sample_data;
-------------------------------------------------
-- Region: 5. IFNULL and IF (MySQL Shorthand)
-------------------------------------------------
/*
5.1 IFNULL is equivalent to COALESCE with two arguments.
*/
SELECT
name,
IFNULL(salary, 0.00) AS effective_salary
FROM sample_data;
/*
5.2 IF(condition, true_value, false_value) is a compact alternative
to a two-branch CASE expression.
*/
SELECT
name,
IF(salary IS NULL, 'Unset', FORMAT(salary, 2)) AS salary_display
FROM sample_data;
-------------------------------------------------
-- Region: 6. CONVERT_TZ (AT TIME ZONE Equivalent)
-------------------------------------------------
/*
6.1 MySQL uses CONVERT_TZ instead of the AT TIME ZONE syntax.
Requires the time zone tables to be populated
(mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql).
*/
SELECT
name,
NOW() AS server_time,
CONVERT_TZ(NOW(), @@global.time_zone, 'UTC') AS utc_time,
CONVERT_TZ(NOW(), @@global.time_zone, 'US/Pacific') AS pacific_time
FROM sample_data
LIMIT 1;
-------------------------------------------------
-- Region: 7. Optimizer Hints
-------------------------------------------------
/*
7.1 MySQL 8.0 supports inline optimizer hints in SQL comments.
Use /*+ ... */ immediately after SELECT/UPDATE/DELETE/INSERT.
Common hints:
NO_INDEX(tbl, idx) force the optimizer to skip an index
INDEX(tbl, idx) suggest using a specific index
SET_VAR(var=val) set a session variable for one statement
MAX_EXECUTION_TIME(ms) cap query execution time
*/
SELECT /*+ MAX_EXECUTION_TIME(1000) */
name, salary
FROM sample_data
WHERE department = 'IT';
/*
7.2 STRAIGHT_JOIN fixes the join order to left-to-right (like FORCE ORDER).
*/
SELECT STRAIGHT_JOIN
s.name,
s.department
FROM sample_data s
JOIN sample_data s2 ON s.id = s2.id
WHERE s.department = 'IT';
-------------------------------------------------
-- Region: 8. LAST_INSERT_ID (OUTPUT Equivalent)
-------------------------------------------------
/*
8.1 After an INSERT, LAST_INSERT_ID() returns the AUTO_INCREMENT
value for the row just inserted — the closest MySQL equivalent
to the SQL Server OUTPUT clause for capturing generated keys.
*/
INSERT INTO sample_data (name, age, salary, department, notes)
VALUES ('Frank', 32, 70000.00, 'Marketing', 'Inserted by example');
SELECT LAST_INSERT_ID() AS newly_inserted_id;
/*
8.2 For multi-row inserts LAST_INSERT_ID() returns the id of the
first inserted row in the batch.
*/
INSERT INTO sample_data (name, age, salary, department, notes)
VALUES
('Grace', 29, 65000.00, 'Marketing', NULL),
('Henry', 45, 95000.00, 'Finance', NULL);
SELECT LAST_INSERT_ID() AS first_id_of_batch;
-------------------------------------------------
-- Region: End of Script
-------------------------------------------------