Code Lab е в разработка. Постепенно добавяме нови уроци и подобрения. Прогресът може да бъде изтрит.
Зареждане…
Code Lab е в разработка. Постепенно добавяме нови уроци и подобрения. Прогресът може да бъде изтрит.
Зареждане…
Code Lab е в разработка. Постепенно добавяме нови уроци и подобрения. Прогресът може да бъде изтрит.
SQL / POSTGRESQL / Учене / LESSON 11
Капстоун: фиксиран период, CTE стъпки, date_trunc, LAG и безопасно изчисляване на промяна. LAG(revenue) OVER (ORDER BY month_start) връща стойността от ПРЕДИШНИЯ НАЛИЧЕН ред в реда на прозореца — не от предишния календарен месец. Ако в данните няма поръчки за един месец, този месец просто липсва като ред и LAG ще сочи към месеца преди него. За първия ред няма предишен и LAG връща NULL.
Затова промяната се пази: разлика = revenue - prev_revenue е NULL при първия месец; процентът 100.0 * (revenue - prev_revenue) / prev_revenue трябва да обработва и NULL, и делене на нула: CASE WHEN prev_revenue IS NULL OR prev_revenue = 0 THEN NULL ELSE ... END. Закръглявай с ROUND(x, 2).
Върху LAG не може да се филтрира в същото SELECT — първо изчисли в CTE, после филтрирай във външната заявка. Така се прави и „топ N“: CTE изчислява промените, външната заявка слага ORDER BY ... LIMIT N. Прозоречният ORDER BY не подрежда резултата — крайният ORDER BY е задължителен за предвиден изглед.
Чести грешки: допускане, че LAG е „предишният месец“ при липсващи данни; делене на нула; незащитен NULL за първия ред; забравен крайният ORDER BY; граница <= вместо < за следващия първи ден.
Мини пример:
SELECT order_date, total, LAG(total) OVER (ORDER BY order_date, id) AS prev_total FROM orders ORDER BY order_date, id;
Работни таблици за тази задача. Оценяването ползва и други набори със същата схема.
| id | name | category | price |
|---|---|---|---|
| 1 | Atlas | books | 30 |
| 2 | Novel | books | 15 |
| 3 | Comic | books | 14.99 |
| 4 | Lamp | home | 29.99 |
| 5 | Vase | home | 30 |
| 6 | Rug | home | 45 |
| 7 | Hammer | tools | 15 |
| 8 | Drill | tools | 60 |
| 9 | Tape | tools | 15 |
| 10 | Candle | NULL | 8.5 |
| 11 | Gift Card | NULL | 25 |
| id | name | city |
|---|---|---|
| 1 | Mira | Sofia |
| 2 | Niko | Varna |
| 3 | Iva | Sofia |
| 4 | Alex | NULL |
| 5 | Boris | Plovdiv |
| 6 | Lena | Varna |
| 7 | Petya | Sofia |
| id | customer_id | total | order_date |
|---|---|---|---|
| 1 | 1 | 120 | 2024-01-05 |
| 2 | 1 | 35.5 | 2024-01-20 |
| 3 | 2 | 40 | 2024-01-20 |
| 4 | 3 | 99.99 | 2024-01-31 |
| 5 | NULL | 60 | 2024-02-01 |
| 6 | 1 | 40 | 2024-02-01 |
| 7 | 2 | 75.25 | 2024-02-14 |
| 8 | 3 | 100 | 2024-02-15 |
| 9 | 5 | 22 | 2024-02-15 |
| 10 | 1 | 39.99 | 2024-02-29 |
| 11 | 2 | 55 | 2024-03-01 |
| 12 | 3 | 18 | 2024-03-10 |
| 13 | 1 | 130 | 2024-03-15 |
| 14 | 2 | 40 | 2024-03-15 |
| 15 | 2 | 12.5 | 2024-03-31 |
| 16 | 3 | 47 | 2024-04-01 |
Очаквани колони: month_start, revenue, prev_revenue, revenue_change, change_pct · редът на редовете се проверява
Очакван резултат (показаните данни):
Зареждане…Капстоун: фиксиран период, CTE стъпки, date_trunc, LAG и безопасно изчисляване на промяна. LAG(revenue) OVER (ORDER BY month_start) връща стойността от ПРЕДИШНИЯ НАЛИЧЕН ред в реда на прозореца — не от предишния календарен месец. Ако в данните няма поръчки за един месец, този месец просто липсва като ред и LAG ще сочи към месеца преди него. За първия ред няма предишен и LAG връща NULL. Затова промяната се пази: разлика = revenue - prev_revenue е NULL при първия месец; процентът 100.0 * (revenue - prev_revenue) / prev_revenue трябва да обработва и NULL, и делене на нула: CASE WHEN prev_revenue IS NULL OR prev_revenue = 0 THEN NULL ELSE ... END. Закръглявай с ROUND(x, 2). Върху LAG не може да се филтрира в същото SELECT — първо изчисли в CTE, после филтрирай във външната заявка. Така се прави и „топ N“: CTE изчислява промените, външната заявка слага ORDER BY ... LIMIT N. Прозоречният ORDER BY не подрежда резултата — крайният ORDER BY е задължителен за предвиден изглед. Чести грешки: допускане, че LAG е „предишният месец“ при липсващи данни; делене на нула; незащитен NULL за първия ред; забравен крайният ORDER BY; граница <= вместо < за следващия първи ден.
QUERY STANDBY
›