-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy path123_Solutions4.sql
229 lines (148 loc) · 5.57 KB
/
123_Solutions4.sql
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
DROP DATABASE IF EXISTS CAVE_TEST;
CREATE DATABASE CAVE_TEST;
USE CAVE_TEST;
--
-- 1. Create table of words and adjectives and populate it.
--
create table words(id int primary key auto_increment, noun varchar(20) not null, adjective varchar(20) not null);
insert into words (noun, adjective) values ("sun", "fast");
insert into words (noun, adjective) values ("chair", "slow");
insert into words (noun, adjective) values ("stone", "new");
insert into words (noun, adjective) values ("dog", "greasy");
insert into words (noun, adjective) values ("cat", "blue");
insert into words (noun, adjective) values ("book", "high");
insert into words (noun, adjective) values ("sky", "evil");
insert into words (noun, adjective) values ("tree", "beautiful");
insert into words (noun, adjective) values ("apple", "sly");
insert into words (noun, adjective) values ("head", "ordinary");
select * from words;
--
-- Create procedure that produces lists of nouns and adjectives separately
--
delimiter $$
create procedure create_lists(out nouns text, out adjectives text)
begin
declare finished bool default false;
declare the_noun varchar(20);
declare the_adjective varchar(20);
declare first boolean default true;
declare cur cursor for select noun, adjective from words order by id;
declare continue handler for not found set finished := true;
set nouns := "";
set adjectives := "";
open cur;
the_loop: loop
fetch cur into the_noun, the_adjective;
if finished then
leave the_loop;
end if;
-- Deal with the comma. Only add it if
-- this isn't the first record.
if first then
set first := false;
else
set nouns := concat(nouns, ",");
set adjectives := concat(adjectives, ",");
end if;
-- Now concat the results from the table.
set nouns := concat(nouns, the_noun);
set adjectives := concat(adjectives, the_adjective);
end loop;
close cur;
end$$
delimiter ;
call create_lists(@nouns, @adjectives);
select @nouns, @adjectives;
drop procedure create_lists;
--
-- 2. Generate table of "star" names.alter
--
create table stars(id int primary key auto_increment, name varchar(40) not null);
delimiter $$
create procedure create_stars()
begin
declare the_noun varchar(20);
declare the_adjective varchar(20);
declare finished boolean default false;
declare nouns_cursor cursor for select noun from words order by rand();
declare adjectives_cursor cursor for select adjective from words order by rand();
declare continue handler for not found set finished := true;
open nouns_cursor;
open adjectives_cursor;
the_loop: loop
fetch nouns_cursor into the_noun;
fetch adjectives_cursor into the_adjective;
if finished then
leave the_loop;
end if;
-- Uppercase first letters
set the_adjective = concat(ucase(left(the_adjective, 1)), substring(the_adjective, 2));
set the_noun = concat(ucase(left(the_noun, 1)), substring(the_noun, 2));
insert into stars (name) values (concat(the_adjective, " ", the_noun));
end loop;
close nouns_cursor;
close adjectives_cursor;
end$$
delimiter ;
call create_stars();
drop procedure create_stars;
select * from stars;
set sql_safe_updates=0;
delete from stars;
--
-- 3 and 4
--
alter table stars add column born date;
alter table stars add column died date;
delimiter $$
create procedure create_stars_with_dates()
not deterministic
begin
declare the_noun varchar(20);
declare the_adjective varchar(20);
declare born_date date;
declare died_date date;
declare min_died date;
declare max_died date;
declare days_lifespan int;
declare finished boolean default false;
declare nouns_cursor cursor for select noun from words order by rand();
declare adjectives_cursor cursor for select adjective from words order by rand();
declare continue handler for not found set finished := true;
open nouns_cursor;
open adjectives_cursor;
the_loop: loop
fetch nouns_cursor into the_noun;
fetch adjectives_cursor into the_adjective;
if finished then
leave the_loop;
end if;
-- Uppercase first letters
set the_adjective = concat(ucase(left(the_adjective, 1)), substring(the_adjective, 2));
set the_noun = concat(ucase(left(the_noun, 1)), substring(the_noun, 2));
-- Figure out birth date; at least 20 years ago, and not more than 60 years before
-- that (80 years total maximum)
select date(now()) - interval 20 year - interval 365*60*rand() day into born_date;
-- When was the earliest they could have died? At least 19 years after being born.
select born_date + interval 19 year into min_died;
set died_date := null;
if rand() <= 0.4 then
-- When was the latest they could have died? (Today)
select date(now()) into max_died;
-- Calculate a random fraction of the interval between the birth date
-- and maximum death date.
select datediff(max_died, min_died)*rand() into days_lifespan;
-- Add this number of days to when they were born to get the death date.
select born_date + interval 19 year + interval days_lifespan day into died_date;
end if;
insert into stars (name, born, died) values (concat(the_adjective, " ", the_noun), born_date, died_date);
end loop;
close nouns_cursor;
close adjectives_cursor;
end$$
delimiter ;
delete from stars;
call create_stars_with_dates();
drop procedure create_stars_with_dates;
select from_days(datediff(died, born)) from stars where died is not null;
select * from stars;