@@ -21,42 +21,49 @@ INSERT INTO product (product_id, product_name) VALUES
2121
2222CREATE TABLE sales (
2323 product_id INT ,
24- period_start VARCHAR ( 20 ) ,
24+ period_start DATE ,
2525 period_end DATE ,
26- average_daily_sales INT
26+ average_daily_sales INT ,
27+ FOREIGN KEY (product_id) REFERENCES Product(product_id)
2728);
2829
29- INSERT INTO sales (product_id, period_start, period_end, average_daily_sales) VALUES
30- (1 , ' 2023-07-01' , ' 2023-07-31' , 150 ),
31- (2 , ' 2023-06-01' , ' 2023-06-30' , 45 ),
32- (3 , ' 2023-05-01' , ' 2023-05-31' , 2 ),
33- (1 , ' 2023-01-01' , ' 2023-01-31' , 140 ),
34- (2 , ' 2022-12-01' , ' 2022-12-31' , 60 ),
35- (3 , ' 2023-02-01' , ' 2023-02-28' , 5 );
30+ INSERT INTO Sales (product_id, period_start, period_end, average_daily_sales) VALUES
31+ (1 , ' 2019-01-25' , ' 2019-02-28' , 100 ),
32+ (2 , ' 2018-12-01' , ' 2020-01-01' , 10 ),
33+ (3 , ' 2019-12-01' , ' 2020-01-31' , 1 );
3634```
3735
36+ ### Expected Output
37+
38+
39+ | product_id | report_year | total_amount |
40+ | ------------| -------------| --------------|
41+ | 1 | 2019 | 3500 |
42+ | 2 | 2018 | 310 |
43+ | 2 | 2019 | 3650 |
44+ | 2 | 2020 | 10 |
45+ | 3 | 2019 | 31 |
46+ | 3 | 2020 | 31 |
47+
48+
3849
3950### Solution Query
4051
4152``` sql
42- SELECT b .product_id ,
43- a .product_name ,
44- a .yr AS report_year,
45- CASE
46- WHEN YEAR(b .period_start ) = YEAR(b .period_end ) AND a .yr = YEAR(b .period_start ) THEN DATEDIFF(b .period_end ,b .period_start ) + 1
47- WHEN a .yr = YEAR(b .period_start ) THEN DATEDIFF(DATE_FORMAT(b .period_start ,' %Y-12-31' ), b .period_start )+ 1
48- WHEN a .yr = YEAR(b .period_end ) THEN DAYOFYEAR(b .period_end )
49- WHEN a .yr > YEAR(b .period_start ) AND a .yr < YEAR(b .period_end ) THEN 365
50- ELSE 0
51- END * average_daily_sales AS total_amount
52- FROM (
53- SELECT product_id,product_name,' 2018' AS yr FROM Product
54- UNION
55- SELECT product_id,product_name,' 2019' AS yr FROM Product
56- UNION
57- SELECT product_id,product_name,' 2020' AS yr FROM Product
58- ) a
59- JOIN Sales b ON a .product_id = b .product_id
60- HAVING total_amount > 0
61- ORDER BY 1 , 3
53+ -- easy solution using RECURSIVE CTE.
54+
55+ WITH RECURSIVE all_dates AS (
56+ SELECT MIN (period_start) as dates, MAX (period_end) as max_date
57+ FROM sales
58+ UNION ALL
59+ SELECT dates + 1 as dates, max_date
60+ FROM all_dates
61+ WHERE dates < max_date
62+ )
63+ SELECT product_id,
64+ EXTRACT(YEAR FROM dates) as report_year,
65+ SUM (average_daily_sales) as total_amount
66+ FROM all_dates ad JOIN sales s ON dates BETWEEN period_start AND period_end
67+ GROUP BY 1 , 2
68+ ORDER BY 1 , 2
6269```
0 commit comments