Changes between Initial Version and Version 1 of AdvancedReport13


Ignore:
Timestamp:
09/25/26 16:23:39 (5 days ago)
Author:
201178
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AdvancedReport13

    v1 v1  
     1= Откривање на аномалии: нарачки со невообичаено високи вредности =
     2
     3== Опис ==
     4
     5Извештајот ги прикажува нарачките чија вредност е повеќе од 2 стандардни отстапувања над просекот за тој келнер. Користи статистички функции (STDDEV) и корелационен потпрашалник за споредба со глобалниот просек.
     6
     7== SQL решение ==
     8
     9{{{
     10CREATE OR REPLACE FUNCTION project.get_anomalous_orders()
     11RETURNS TABLE (
     12    order_id INT,
     13    waiter_name TEXT,
     14    order_total NUMERIC,
     15    waiter_avg NUMERIC,
     16    waiter_stddev NUMERIC,
     17    z_score NUMERIC,
     18    deviation_level TEXT
     19)
     20LANGUAGE sql
     21AS $$
     22    WITH order_totals AS (
     23        SELECT
     24            o.order_id AS oid,
     25            o.user_id AS uid,
     26            SUM(oi.quantity * oi.unit_price)::numeric AS total
     27        FROM project.orders o
     28        JOIN project.order_item oi ON oi.order_id = o.order_id
     29        WHERE o.status = 'ПЛАТЕНА'
     30        GROUP BY o.order_id, o.user_id
     31    ),
     32    waiter_stats AS (
     33        SELECT
     34            ot.uid,
     35            AVG(ot.total)::numeric AS avg_total,
     36            STDDEV(ot.total)::numeric AS stddev_total,
     37            COUNT(*) AS num_orders
     38        FROM order_totals ot
     39        GROUP BY ot.uid
     40    )
     41    SELECT
     42        ot.oid,
     43        (u.first_name || ' ' || u.last_name)::TEXT,
     44        ot.total,
     45        ROUND(ws.avg_total, 2),
     46        ROUND(ws.stddev_total, 2),
     47        ROUND(((ot.total - ws.avg_total) / NULLIF(ws.stddev_total, 0))::numeric, 2),
     48        CASE
     49            WHEN (ot.total - ws.avg_total) / NULLIF(ws.stddev_total, 0) > 3
     50                 THEN 'ЕКСТРЕМНО ВИСОКА'
     51            WHEN (ot.total - ws.avg_total) / NULLIF(ws.stddev_total, 0) > 2
     52                 THEN 'ВИСОКА'
     53            ELSE 'НОРМАЛНА'
     54        END::TEXT
     55    FROM order_totals ot
     56    JOIN waiter_stats ws ON ws.uid = ot.uid
     57    JOIN project.app_user u ON u.user_id = ot.uid
     58    WHERE ws.num_orders >= 1
     59      AND (ot.total - ws.avg_total) / NULLIF(ws.stddev_total, 0) > 1
     60    ORDER BY 6 DESC;
     61$$;
     62}}}
     63
     64== Релациона алгебра ==
     65
     66{{{
     67O(order_id, user_id, status)
     68OI(order_id, quantity, unit_price)
     69U(user_id, first_name, last_name)
     70
     71J1 ← O ⨝ O.order_id = OI.order_id OI
     72F1 ← σ status='ПЛАТЕНА' (J1)
     73G1 ← γ order_id, user_id; SUM(quantity * unit_price) → order_total (F1)
     74
     75G2 ← γ user_id; AVG(order_total) → avg_total,
     76                  STDDEV(order_total) → stddev_total,
     77                  COUNT(*) → num_orders (G1)
     78
     79J2 ← G1 ⨝ G1.user_id = G2.user_id G2
     80J3 ← J2 ⨝ U
     81F2 ← σ num_orders ≥ 1 ∧ (order_total - avg_total)/stddev_total > 1 (J3)
     82
     83R ← π order_id, waiter_name, order_total, waiter_avg,
     84      waiter_stddev, z_score, deviation_level (F2)
     85
     86R_final ← τ z_score DESC (R)
     87}}}