| | 1 | = Просечно време помеѓу нарачка и плаќање = |
| | 2 | |
| | 3 | == Опис == |
| | 4 | |
| | 5 | Извештајот го пресметува просечното време (во минути) помеѓу креирањето на нарачката и нејзиното плаќање, групирано по келнер. Овозможува идентификување на најефикасните келнери. |
| | 6 | |
| | 7 | == SQL решение == |
| | 8 | |
| | 9 | {{{ |
| | 10 | CREATE OR REPLACE FUNCTION get_avg_time_to_payment() |
| | 11 | RETURNS TABLE ( |
| | 12 | user_id INT, |
| | 13 | waiter_name TEXT, |
| | 14 | total_orders BIGINT, |
| | 15 | avg_minutes_to_payment NUMERIC, |
| | 16 | min_minutes NUMERIC, |
| | 17 | max_minutes NUMERIC |
| | 18 | ) |
| | 19 | LANGUAGE plpgsql |
| | 20 | AS $$ |
| | 21 | BEGIN |
| | 22 | RETURN QUERY |
| | 23 | SELECT |
| | 24 | u.user_id, |
| | 25 | (u.first_name || ' ' || u.last_name)::TEXT AS waiter_name, |
| | 26 | COUNT(o.order_id) AS total_orders, |
| | 27 | ROUND(AVG(EXTRACT(EPOCH FROM (p.payment_date - o.created_at)) / 60), 2) AS avg_minutes_to_payment, |
| | 28 | MIN(EXTRACT(EPOCH FROM (p.payment_date - o.created_at)) / 60) AS min_minutes, |
| | 29 | MAX(EXTRACT(EPOCH FROM (p.payment_date - o.created_at)) / 60) AS max_minutes |
| | 30 | FROM project.orders o |
| | 31 | JOIN project.payment p ON p.order_id = o.order_id |
| | 32 | JOIN project.app_user u ON u.user_id = o.user_id |
| | 33 | WHERE o.status = 'ПЛАТЕНА' |
| | 34 | GROUP BY u.user_id, u.first_name, u.last_name |
| | 35 | HAVING COUNT(o.order_id) >= 5 |
| | 36 | ORDER BY avg_minutes_to_payment ASC; |
| | 37 | END; |
| | 38 | $$; |
| | 39 | }}} |
| | 40 | |
| | 41 | == Релациона алгебра == |
| | 42 | |
| | 43 | {{{ |
| | 44 | U(user_id, first_name, last_name) |
| | 45 | O(order_id, user_id, created_at, status) |
| | 46 | P(payment_id, order_id, payment_date) |
| | 47 | |
| | 48 | J1 ← O ⨝ O.order_id = P.order_id P |
| | 49 | J2 ← J1 ⨝ O.user_id = U.user_id U |
| | 50 | |
| | 51 | F1 ← σ status='ПЛАТЕНА' (J2) |
| | 52 | |
| | 53 | G ← γ user_id, waiter_name; |
| | 54 | COUNT(order_id) → total_orders, |
| | 55 | AVG((payment_date - created_at)/60) → avg_minutes_to_payment, |
| | 56 | MIN((payment_date - created_at)/60) → min_minutes, |
| | 57 | MAX((payment_date - created_at)/60) → max_minutes (F1) |
| | 58 | |
| | 59 | F2 ← σ total_orders ≥ 5 (G) |
| | 60 | |
| | 61 | R ← π user_id, waiter_name, total_orders, avg_minutes_to_payment, min_minutes, max_minutes (F2) |
| | 62 | |
| | 63 | R_final ← τ avg_minutes_to_payment ASC (R) |
| | 64 | }}} |