2024
Day 1
Day 1
AS (
WITH latest_list
SELECT
child_id,MAX(submitted_date) AS latest
FROM wish_lists
GROUP BY child_id
),
AS (
fav_colors
SELECT
wl.child_id,::json ->> 'colors' AS color_array
wl.wishes
FROM wish_lists AS wl
INNER JOIN latest_list AS ll ONwl.child_id = ll.child_id
wl.submitted_date = ll.latest
AND
),
AS (
wishes
SELECT
wl.child_id,::json ->> 'first_choice' AS primary_wish,
wl.wishes::json ->> 'second_choice' AS backup_wish,
wl.wishes::json -> 'colors')::json ->> 0 AS favorite_color,
(wl.wishesJSON_ARRAY_LENGTH(fc.color_array::json) AS n_colors
FROM wish_lists AS wl
INNER JOIN fav_colors AS fcwl.child_id = fc.child_id
ON
INNER JOIN latest_list AS ll ONwl.child_id = ll.child_id
wl.submitted_date = ll.latest
AND
),
AS (
complexity
SELECT
toy_name,
CASEdifficulty_to_make = 1 THEN 'Simple Gift'
WHEN difficulty_to_make = 2 THEN 'Moderate Gift'
WHEN 'Complex Gift'
ELSE
END AS gift_complexity,
CASEcategory = 'educational' THEN 'Learning Workshop'
WHEN category = 'outdoor' THEN 'Outdoor Workshop'
WHEN 'General Workshop'
ELSE
END AS workshop_assignment
FROM toy_catalogue
)
SELECT
ch.name,
wsh.primary_wish,
wsh.backup_wish,
wsh.favorite_color,
wsh.n_colors,
cmplx.gift_complexity,
cmplx.workshop_assignment
FROM children AS ch= wsh.child_id
INNER JOIN wishes AS wsh ON ch.child_id = cmplx.toy_name
INNER JOIN complexity AS cmplx ON wsh.primary_wish
ORDER BY ch.name5; LIMIT
name primary_wish backup_wish favorite_color
1 Abbie Barbie dolls Toy musical instruments Green
2 Abbigail Jump ropes Action figures Yellow
3 Abdullah Yo-yos Yo-yos Yellow
4 Abdullah Toy musical instruments Barbie dolls Pink
5 Abelardo Toy trains Board games Yellow
n_colors gift_complexity workshop_assignment
1 5 Moderate Gift General Workshop
2 1 Simple Gift Outdoor Workshop
3 1 Simple Gift General Workshop
4 2 Complex Gift Learning Workshop
5 4 Complex Gift General Workshop
0.069 sec elapsed
Day 2
Day 2
AS (
WITH combined * FROM letters_a
SELECT
UNION ALL* FROM letters_b
SELECT
),
AS (
decoded
SELECT*,
CHR(value) AS string
FROM combined
WHERE65 AND 90)
(value BETWEEN OR (value BETWEEN 97 AND 122)
OR (value IN (32, 33, 44, 46))
)
STRING_AGG(string, '') FROM decoded; SELECT
string_agg
1 Dear Santa, I hope this letter finds you well in the North Pole! I want a SQL course for Christmas!
0.006 sec elapsed
Day 3
Day 3
-- noqa: disable=LT05
AS (
WITH parsed_menu
SELECTXPATH('//food_item_id/text()', menu_data))::text [] AS array_food_item,
(
CASEARRAY_LENGTH(XPATH('//total_present/text()', menu_data), 1) > 0
WHEN THEN (XPATH('//total_present/text()', menu_data))[1]::text::integer
ARRAY_LENGTH(XPATH('//total_count/text()', menu_data), 1) > 0
WHEN THEN (XPATH('//total_count/text()', menu_data))[1]::text::integer
ARRAY_LENGTH(XPATH('//total_guests/text()', menu_data), 1) > 0
WHEN THEN (XPATH('//total_guests/text()', menu_data))[1]::text::integer
END AS n_guests
FROM christmas_menus
)
SELECTUNNEST(array_food_item) AS food_item,
COUNT(*) AS n
FROM parsed_menu> 78
WHERE n_guests
GROUP BY food_item
ORDER BY n DESC1; LIMIT
food_item n
1 493 117
1.568 sec elapsed
Day 4
Day 4
SELECT
toy_id,
(COUNT(*)
SELECT FROM (
UNNEST(new_tags)
SELECT
EXCEPTUNNEST(previous_tags)
SELECT
)
) AS added,
(COUNT(*)
SELECT FROM (
UNNEST(previous_tags)
SELECT
INTERSECTUNNEST(new_tags)
SELECT
)
) AS unchanged,
(COUNT(*)
SELECT FROM (
UNNEST(previous_tags)
SELECT
EXCEPTUNNEST(new_tags)
SELECT
)
) AS removed
FROM toy_production
ORDER BY added DESC1; LIMIT
toy_id added unchanged removed
1 2726 98 2 0
0.171 sec elapsed
Day 5
Day 5
AS (
WITH previous
SELECT
production_date,
toys_produced,LAG(toys_produced, 1, NULL)
OVER (ORDER BY production_date)
AS previous_day_production
FROM toy_production
)
SELECT
tp.production_date,
pr.toys_produced,
pr.previous_day_production,- pr.previous_day_production AS production_change,
tp.toys_produced ROUND(
- pr.previous_day_production)
(tp.toys_produced / (pr.previous_day_production * 1.0) * 100.0, 2
) AS production_change_percentage
FROM toy_production AS tp= pr.production_date
INNER JOIN previous AS pr ON tp.production_date NULL
WHERE pr.previous_day_production IS NOT
ORDER BY production_change_percentage DESC1; LIMIT
production_date toys_produced previous_day_production production_change
1 2017-03-20 2327 3 2324
production_change_percentage
1 77466.67
0.04 sec elapsed
Day 6
Day 6
SELECT
ch.name AS child_name,
gi.name AS gift_name,
gi.price AS gift_price
FROM children AS ch= gi.child_id
INNER JOIN gifts AS gi ON ch.child_id > (SELECT AVG(mp.price) FROM gifts AS mp)
WHERE gi.price
ORDER BY gi.price ASC5; LIMIT
child_name gift_name gift_price
1 Hobart art easel 497.44
2 Lindsey wizard chess set 497.52
3 Reba bubble machine 497.89
4 Reina talking globe 497.91
5 Brenden talking globe 498.25
0.037 sec elapsed
Day 7
Day 7
AS (
WITH min_experience ON (primary_skill)
SELECT DISTINCT
elf_id,
years_experience,
primary_skill
FROM workshop_elves
ORDER BY primary_skill ASC, years_experience ASC, elf_id ASC
),
AS (
max_experience ON (primary_skill)
SELECT DISTINCT
elf_id,
years_experience,
primary_skill
FROM workshop_elves
ORDER BY primary_skill ASC, years_experience DESC, elf_id ASC
)
SELECT
max_exp.elf_id AS elf_1_id,
min_exp.elf_id AS elf_2_id,
max_exp.primary_skill AS shared_skill
FROM min_experience AS min_exp
INNER JOIN max_experience AS max_exp= max_exp.primary_skill
ON min_exp.primary_skill
ORDER BY min_exp.primary_skill3; LIMIT
elf_1_id elf_2_id shared_skill
1 4153 3611 Gift sorting
2 10497 1016 Gift wrapping
3 50 13551 Toy making
0.392 sec elapsed
Day 8
Day 8
AS (
WITH RECURSIVE managers
SELECT
s1.staff_id,
s1.staff_name,
s1.manager_id
FROM staff AS s1
UNION ALL
SELECT
s2.staff_id,
s2.staff_name,
s2.manager_id
FROM staff AS s2
INNER JOIN managers AS mgmts2.manager_id = mgmt.staff_id
ON
)
COUNT(*) AS n
SELECT
FROM managers
GROUP BY staff_id
ORDER BY n DESC1; LIMIT
n
1 24
2.382 sec elapsed
Day 9
Day 9
AS (
WITH avg_exercise
SELECT
reindeer_id,
exercise_name,AVG(speed_record) AS avg_speed
FROM training_sessions
GROUP BY reindeer_id, exercise_name
),
AS (
max_avg_speed
SELECT
reindeer_id,MAX(avg_speed) AS max_avg_speed
FROM avg_exercise
GROUP BY reindeer_id
)
SELECT
re.reindeer_name,ROUND(mas.max_avg_speed, 2) AS top_speed
FROM max_avg_speed AS mas= re.reindeer_id
INNER JOIN reindeers AS re ON mas.reindeer_id != 'Rudolph'
WHERE re.reindeer_name
ORDER BY top_speed DESC3; LIMIT
reindeer_name top_speed
1 Cupid 88.64
2 Blitzen 88.38
3 Vixen 88.01
0.01 sec elapsed
Day 10
Day 10
AS (
WITH drinks
SELECT
date,SUM(
drink_name = 'Eggnog' THEN quantity ELSE 0 END
CASE WHEN
) AS eggnog,SUM(
drink_name = 'Hot Cocoa' THEN quantity ELSE 0 END
CASE WHEN
) AS hot_cocoa,SUM(
CASEdrink_name = 'Peppermint Schnapps' THEN quantity ELSE 0
WHEN
END
) AS peppermint_schnapps
FROM drinks
GROUP BY date
)
SELECT date FROM drinks
WHERE1 = 1
= 198
AND eggnog = 38
AND hot_cocoa = 298; AND peppermint_schnapps
date
1 2024-03-14
0.009 sec elapsed
Day 11
Day 11
SELECT
field_name,
harvest_year,
season,ROUND(AVG(trees_harvested) OVER (
PARTITION BY field_name
ORDER BY
harvest_year,
CASEseason = 'Spring' THEN 1
WHEN season = 'Summer' THEN 2
WHEN season = 'Fall' THEN 3
WHEN season = 'Winter' THEN 4
WHEN
END2 PRECEDING
ROWS BETWEEN
AND CURRENT ROW2) AS moving_ave
),
FROM
treeharvests
ORDER BY
moving_ave DESC1; LIMIT
field_name harvest_year season moving_ave
1 Northern Gardens 62 2024 Winter 327.67
0.009 sec elapsed
Day 12
Day 12
AS (
WITH gift_counts
SELECT
gi.gift_name,COUNT(*) AS n_req
FROM gift_requests AS reqreq.gift_id = gi.gift_id
LEFT JOIN gifts AS gi ON
GROUP BY gi.gift_name
)
SELECT
gift_name,ROUND(PERCENT_RANK() OVER (
ORDER BY n_req::numeric, 2) AS percentile
)
FROM
gift_counts
ORDER BY percentile DESC, gift_name ASC20; LIMIT
gift_name percentile
1 costume trunk 0.92
2 finger paint set 0.92
3 hoverboard 0.92
4 jump rope 0.92
5 magic kit 0.92
6 musical keyboard 0.92
7 rocking horse 0.92
8 talking globe 0.92
9 toy submarine 0.92
10 chemistry set 0.86
11 friendship bracelet maker 0.86
12 learning tablet 0.86
13 magic 8 ball 0.86
14 magic wand 0.86
15 toy rocket 0.86
16 bowling set 0.72
17 building blocks 0.72
18 crystal growing kit 0.72
19 flying drone 0.72
20 magic treehouse 0.72
0.035 sec elapsed
Day 13
Day 13
AS (
WITH email_addresses
SELECT
name,
email,SPLIT_PART(email, '@', 2) AS domain_name
UNNEST(email_addresses) AS email
FROM contact_list,
)
SELECT
domain_name,COUNT(*) AS n_users
FROM
email_addresses
GROUP BY
domain_name
ORDER BY n_users DESC5; LIMIT
domain_name n_users
1 bells.org 155
2 stockings.net 154
3 gifts.biz 149
4 bells.com 146
5 holly.biz 145
0.012 sec elapsed
Day 14
Day 14
AS (
WITH receipts JSONB_ARRAY_ELEMENTS(cleaning_receipts) AS receipt
SELECT
FROM santarecords
),
AS (
unnested_receipt_items
SELECT->> 'drop_off' AS drop_off_date,
receipt ->> 'garment' AS garment,
receipt ->> 'color' AS color
receipt
FROM receipts
)
* FROM unnested_receipt_items
SELECT
WHERE1 = 1
= 'suit'
AND garment = 'green'; AND color
drop_off_date garment color
1 2024-12-22 suit green
2 2024-12-22 suit green
3 2024-11-27 suit green
4 2024-11-08 suit green
5 2024-11-28 suit green
6 2024-11-07 suit green
7 2024-11-15 suit green
8 2024-11-06 suit green
0.008 sec elapsed
Day 15
Day 15
AS (
WITH last_location
SELECT coordinate
FROM sleigh_locationstimestamp = (
WHERE MAX(sl.timestamp) FROM sleigh_locations AS sl
SELECT
)
)
SELECT areas.place_name
FROM areas, last_location AS llST_INTERSECTS(areas.polygon, ll.coordinate); WHERE
place_name
1 Paris
0.337 sec elapsed
Day 16
Day 16
AS (
WITH timepoints
SELECT
coordinate,
timestamp AS timestamp_current,LAG(timestamp, 1) OVER (ORDER BY timestamp DESC) AS timestamp_next
FROM sleigh_locations
)
SELECT
areas.place_name,SUM(tp.timestamp_next - tp.timestamp_current) AS duration
FROM timepoints AS tp, areasST_INTERSECTS(areas.polygon, tp.coordinate)
WHERE
GROUP BY areas.place_name ORDER BY duration DESC;
place_name duration
1 Paris 01:30:00
2 New_York 01:15:00
3 London 01:00:00
4 Los_Angeles 01:00:00
5 Tokyo 00:45:00
0.007 sec elapsed
Day 17
Timezones are hard enough, let alone to do them in SQL 😅
Day 18
Couldn’t figure this one out 😕 It asks for a recursive CTE as we used before in Day 8, but this one had a trick to I can’t seem to get
Day 19
Day 19
AS (
WITH avg_last_score
SELECTAVG(
year_end_performance_scores[ARRAY_UPPER(year_end_performance_scores, 1)
]
) AS avg_score
FROM employees
),
AS (
salaries_w_bonus
SELECT
CASE
WHEN
em.year_end_performance_scores[ARRAY_UPPER(em.year_end_performance_scores, 1)
]> (SELECT als.avg_score FROM avg_last_score AS als)
* 1.15
THEN em.salary
ELSE em.salary
END AS salary_w_bonus
FROM employees AS em
)
ROUND(SUM(salary_w_bonus), 2) AS total_salary_paid
SELECT FROM salaries_w_bonus;
total_salary_paid
1 5491552488
0.012 sec elapsed
Day 20
Day 20
SELECT
url,STRING_TO_ARRAY(SPLIT_PART(url, '?', 2), '&') AS query_params,
CARDINALITY(STRING_TO_ARRAY(SPLIT_PART(url, '?', 2), '&')) AS n_params
FROM web_requests
WHERESPLIT_PART(SUBSTRING(url FROM 'utm_source=[\w-]+'), '=', 2)
= 'advent-of-sql'
ORDER BY query_params DESC, url ASC5; LIMIT
url
1 https://prohaska.net?voluptatum_aut_qui=sit_delectus_facere_perferendis&quia_doloremque=deleniti_natus_dolores&ab-quia-pariatur-quisquam=aut_unde_et&utm_source=advent-of-sql
2 https://lebsack.com?voluptatum-sapiente-eaque-et-et=temporibus-assumenda&utm_source=advent-of-sql&sequi-voluptatibus-autem-sequi=cupiditate-consequatur-saepe-nemo-est&placeat-voluptatem-voluptatem=dolorum_laboriosam_aliquid
3 https://heller.com?voluptatum-quam-natus=sunt-dolores-ut-debitis-ab&utm_source=advent-of-sql&utm_source=nisi-soluta&sit_soluta_dolor_voluptatem=qui_ullam_voluptatem_ea_nihil
4 https://williamson.biz?voluptatum-nihil=perferendis_doloremque&utm_source=advent-of-sql&enim-et=repudiandae-fuga-tempore-commodi-autem&aut-et-est-provident-quae=earum-sit-qui-exercitationem-sed
5 http://koepp.name?voluptatum-et-illo-fuga-suscipit=distinctio-voluptatem-et-consequatur-perferendis&ut_deserunt=aliquid-voluptatum&utm_source=advent-of-sql&expedita-ut-nihil=magni_expedita_distinctio_consequatur
query_params
1 {voluptatum_aut_qui=sit_delectus_facere_perferendis,quia_doloremque=deleniti_natus_dolores,ab-quia-pariatur-quisquam=aut_unde_et,utm_source=advent-of-sql}
2 {voluptatum-sapiente-eaque-et-et=temporibus-assumenda,utm_source=advent-of-sql,sequi-voluptatibus-autem-sequi=cupiditate-consequatur-saepe-nemo-est,placeat-voluptatem-voluptatem=dolorum_laboriosam_aliquid}
3 {voluptatum-quam-natus=sunt-dolores-ut-debitis-ab,utm_source=advent-of-sql,utm_source=nisi-soluta,sit_soluta_dolor_voluptatem=qui_ullam_voluptatem_ea_nihil}
4 {voluptatum-nihil=perferendis_doloremque,utm_source=advent-of-sql,enim-et=repudiandae-fuga-tempore-commodi-autem,aut-et-est-provident-quae=earum-sit-qui-exercitationem-sed}
5 {voluptatum-et-illo-fuga-suscipit=distinctio-voluptatem-et-consequatur-perferendis,ut_deserunt=aliquid-voluptatum,utm_source=advent-of-sql,expedita-ut-nihil=magni_expedita_distinctio_consequatur}
n_params
1 4
2 4
3 4
4 4
5 4
0.07 sec elapsed
Day 21
Day 21
AS (
WITH total_sales
SELECTDATE_PART('YEAR', sale_date) AS sale_year,
DATE_PART('QUARTER', sale_date) AS sale_quarter,
SUM(amount) AS sale_amount
FROM sales
GROUP BY sale_year, sale_quarter
)
SELECT
sale_year,
sale_quarter,
sale_amount,ROUND(
sale_amount/ LAG(sale_amount) OVER (ORDER BY sale_year, sale_quarter), 2
) AS growth_rate
FROM total_sales
ORDER BY growth_rate DESC NULLS LAST5; LIMIT
sale_year sale_quarter sale_amount growth_rate
1 1997 4 481323 1.40
2 2022 3 460742 1.21
3 2007 2 488715 1.18
4 2000 2 520574 1.18
5 2004 2 501878 1.17
0.015 sec elapsed
Day 22
Day 22
COUNT(elf_name) AS numofelveswithsql
SELECT
FROM elves'SQL' = ANY(STRING_TO_ARRAY(skills, ',')); WHERE
numofelveswithsql
1 2488
0.023 sec elapsed
Day 23
Day 23
AS (
WITH lag_values
SELECTLAG(id, 1) OVER (ORDER BY id) + 1 AS gap_start,
- 1 AS gap_end,
id - LAG(id, 1) OVER (ORDER BY id) AS gap
id
FROM sequence_table
),
AS (
long_gaps
SELECT
gap_start,
gap_end,GENERATE_SERIES(gap_start, gap_end) AS gap_numbers
FROM lag_values> 1
WHERE gap
)
SELECT
gap_start,
gap_end,ARRAY_AGG(gap_numbers ORDER BY gap_start) AS missing_numbers
FROM long_gaps GROUP BY gap_start, gap_end;
gap_start gap_end missing_numbers
1 997 1001 {997,998,999,1000,1001}
2 3761 3765 {3761,3762,3763,3764,3765}
3 6525 6527 {6525,6526,6527}
4 6529 6529 {6529}
5 9289 9292 {9289,9290,9291,9292}
0.012 sec elapsed
Day 24
Day 24
SELECT
songs.song_title,COUNT(songs.song_title) AS total_plays,
SUM(
< songs.song_duration THEN 1 ELSE 0 END
CASE WHEN up.duration
) AS skipped
FROM songs= up.song_id
INNER JOIN user_plays AS up ON songs.song_id
GROUP BY songs.song_title
ORDER BY total_plays DESC, skipped ASC10; LIMIT
song_title total_plays skipped
1 All I Want For Christmas Is You 562 412
2 The First Noel 541 416
3 Jingle Bells 524 399
4 Deck the Halls 521 395
5 Silent Night 513 389
6 Winter Wonderland 511 386
7 Silver Bells 508 386
8 Let It Snow! Let It Snow! Let It Snow! 506 381
9 White Christmas 504 382
10 Last Christmas 503 385
0.011 sec elapsed