Changes between Version 3 and Version 4 of Advanced Application Development


Ignore:
Timestamp:
09/18/25 16:11:07 (6 weeks ago)
Author:
221531
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Advanced Application Development

    v3 v4  
    11= Report Tables
     2
    23== Main Restaurant Report Summary Table
     4{{{#!sql
    35CREATE TABLE restaurant_weekly_report (
    46    report_id SERIAL PRIMARY KEY,
    57    restaurant_id INT NOT NULL,
    6     report_week DATE NOT NULL, -- Monday of the week
    7     week_number INT NOT NULL, -- Week 1, 2, or 3 (most recent)
     8    report_week DATE NOT NULL,              -- Monday of the week
     9    week_number INT NOT NULL,               -- Week 1, 2, or 3 (most recent)
    810
    911    -- Order Statistics
     
    2022    -- Operational Metrics
    2123    avg_preparation_time_minutes DECIMAL(8,2) DEFAULT 0.00,
    22     peak_hour INTEGER, -- Hour with most orders
    23     busiest_day INTEGER, -- Day of week (0=Sunday, 6=Saturday)
     24    peak_hour INTEGER,                      -- Hour with most orders
     25    busiest_day INTEGER,                    -- Day of week (0=Sunday, 6=Saturday)
    2426
    2527    -- Performance Indicators
    26     completion_rate DECIMAL(5,2) DEFAULT 0.00, -- % of orders completed
     28    completion_rate DECIMAL(5,2) DEFAULT 0.00,       -- % of orders completed
    2729    customer_satisfaction DECIMAL(3,2) DEFAULT 0.00, -- Placeholder for ratings
    2830    orders_per_hour DECIMAL(8,2) DEFAULT 0.00,
     
    3234    last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    3335
    34     CONSTRAINT fk_weekly_report_restaurant FOREIGN KEY (restaurant_id) REFERENCES restaurant(restaurant_id),
    35     CONSTRAINT uq_restaurant_week UNIQUE (restaurant_id, report_week)
     36    CONSTRAINT fk_weekly_report_restaurant
     37        FOREIGN KEY (restaurant_id) REFERENCES restaurant(restaurant_id),
     38    CONSTRAINT uq_restaurant_week
     39        UNIQUE (restaurant_id, report_week)
    3640);
    37 \\
    38 == Popular Items Report Table
     41}}}
     42\\
     43== Popular items report
     44{{{#!sql
    3945CREATE TABLE restaurant_popular_items (
    4046    report_id SERIAL PRIMARY KEY,
     
    4349    item_id INT NOT NULL,
    4450    item_name VARCHAR(100),
    45 
    4651    times_ordered INTEGER DEFAULT 0,
    4752    total_quantity INTEGER DEFAULT 0,
     
    4954    avg_price DECIMAL(8,2) DEFAULT 0.00,
    5055    popularity_rank INTEGER,
    51 
    5256    generated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    5357
    54     CONSTRAINT fk_popular_items_restaurant FOREIGN KEY (restaurant_id) REFERENCES restaurant(restaurant_id),
    55     CONSTRAINT fk_popular_items_item FOREIGN KEY (item_id) REFERENCES item(item_id)
     58    CONSTRAINT fk_popular_items_restaurant
     59        FOREIGN KEY (restaurant_id) REFERENCES restaurant(restaurant_id),
     60    CONSTRAINT fk_popular_items_item
     61        FOREIGN KEY (item_id) REFERENCES item(item_id)
    5662);
    57 \\
    58 == Daily Breakdown Table
     63}}}
     64\\
     65== Daily breakdown
     66{{{#!sql
    5967CREATE TABLE restaurant_daily_breakdown (
    6068    breakdown_id SERIAL PRIMARY KEY,
    6169    restaurant_id INT NOT NULL,
    6270    report_date DATE NOT NULL,
    63     day_of_week INTEGER, -- 0=Sunday, 6=Saturday
    64 
     71    day_of_week INTEGER,                     -- 0=Sunday, 6=Saturday
    6572    daily_orders INTEGER DEFAULT 0,
    6673    daily_revenue DECIMAL(10,2) DEFAULT 0.00,
     
    7077    -- Hourly breakdown (JSON format for flexibility)
    7178    hourly_orders JSONB,
    72 
    7379    generated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    7480
    75     CONSTRAINT fk_daily_breakdown_restaurant FOREIGN KEY (restaurant_id) REFERENCES restaurant(restaurant_id),
    76     CONSTRAINT uq_restaurant_daily UNIQUE (restaurant_id, report_date)
     81    CONSTRAINT fk_daily_breakdown_restaurant
     82        FOREIGN KEY (restaurant_id) REFERENCES restaurant(restaurant_id),
     83    CONSTRAINT uq_restaurant_daily
     84        UNIQUE (restaurant_id, report_date)
    7785);
    78 \\
    79 == Comparative Analysis Table (Week Over Week)
     86}}}
     87\\
     88== Comparative analysis table (week over week)
     89{{{#!sql
    8090CREATE TABLE restaurant_trend_analysis (
    8191    trend_id SERIAL PRIMARY KEY,
     
    8494
    8595    -- 3-week trends
    86     week1_revenue DECIMAL(10,2), -- Most recent week
     96    week1_revenue DECIMAL(10,2),             -- Most recent week
    8797    week2_revenue DECIMAL(10,2),
    8898    week3_revenue DECIMAL(10,2),
    89 
    9099    week1_orders INTEGER,
    91100    week2_orders INTEGER,
     
    93102
    94103    -- Trend indicators
    95     revenue_trend VARCHAR(20), -- 'INCREASING', 'DECREASING', 'STABLE'
     104    revenue_trend VARCHAR(20),               -- 'INCREASING', 'DECREASING', 'STABLE'
    96105    order_trend VARCHAR(20),
    97106
    98107    -- Growth rates
    99     revenue_growth_rate DECIMAL(8,2), -- Week over week %
     108    revenue_growth_rate DECIMAL(8,2),        -- Week over week %
    100109    order_growth_rate DECIMAL(8,2),
    101110
     
    103112    performance_alerts JSONB,
    104113    recommendations JSONB,
    105 
    106114    generated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    107115
    108     CONSTRAINT fk_trend_analysis_restaurant FOREIGN KEY (restaurant_id) REFERENCES restaurant(restaurant_id)
     116    CONSTRAINT fk_trend_analysis_restaurant
     117        FOREIGN KEY (restaurant_id) REFERENCES restaurant(restaurant_id)
    109118);
    110 \\
    111 == Performance Metrics Table
     119}}}
     120\\
     121== Performance metrics table
     122{{{#!sql
    112123CREATE TABLE performance_metrics (
    113124    metric_id SERIAL PRIMARY KEY,
     
    116127    metric_value DECIMAL(8,2),
    117128    recorded_at TIMESTAMP,
    118     CONSTRAINT fk_performance_metrics_restaurant FOREIGN KEY (restaurant_id) REFERENCES RESTAURANT(restaurant_id)
     129
     130    CONSTRAINT fk_performance_metrics_restaurant
     131        FOREIGN KEY (restaurant_id) REFERENCES restaurant(restaurant_id)
    119132);
    120 \\
    121 == Audit Table for Orders
     133}}}
     134\\
     135== Audit table for orders
     136{{{#!sql
    122137CREATE TABLE audit_orders (
    123138    audit_id SERIAL PRIMARY KEY,
     
    128143    change_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    129144);
    130 \\
    131 \\
     145}}}
     146\\
     147
     148
    132149= Utility Functions
    133 \\
    134 == Get Week Start Function
     150== Function to get the Monday of a given week
     151{{{#!sql
    135152CREATE OR REPLACE FUNCTION get_week_start(input_date DATE)
    136     RETURNS DATE AS $$
     153RETURNS DATE AS $$
    137154BEGIN
    138155    RETURN input_date - INTERVAL '1 day' * EXTRACT(DOW FROM input_date);
    139156END;
    140157$$ LANGUAGE plpgsql;
    141 
    142 == Get Week Number Function
     158}}}
     159\\
     160== Function to get week number (1, 2, or 3 for last 3 weeks)
     161{{{#!sql
    143162CREATE OR REPLACE FUNCTION get_week_number(input_date DATE)
    144     RETURNS INTEGER AS $$
     163RETURNS INTEGER AS $$
    145164DECLARE
    146165    week_start DATE;
     
    158177END;
    159178$$ LANGUAGE plpgsql;
    160 
    161 ==  Main Report Generation Function
    162 CREATE OR REPLACE FUNCTION generate_restaurant_weekly_report(p_restaurant_id INT, p_target_date DATE DEFAULT CURRENT_DATE)
    163     RETURNS void AS $$
     179}}}
     180\\
     181== Main report generation function
     182{{{#!sql
     183CREATE OR REPLACE FUNCTION generate_restaurant_weekly_report(
     184    p_restaurant_id INT,
     185    p_target_date DATE DEFAULT CURRENT_DATE
     186)
     187RETURNS void AS $$
    164188DECLARE
    165189    week_start DATE;
     
    218242    INTO v_total_items_sold
    219243    FROM order_items oi
    220         JOIN orders o ON oi.order_id = o.order_id
     244    JOIN orders o ON oi.order_id = o.order_id
    221245    WHERE o.restaurant_id = p_restaurant_id
    222246      AND o.order_date::date BETWEEN week_start AND week_end
    223247      AND o.order_status = 'delivered';
    224248
    225     -- Calculate average preparation time (using performance metrics if available)
     249    -- Calculate average preparation time (if available)
    226250    SELECT COALESCE(AVG(metric_value), 0)
    227251    INTO v_avg_prep_time
     
    241265    LIMIT 1;
    242266
    243     -- Find busiest day of week
     267    -- Find busiest day
    244268    SELECT EXTRACT(dow FROM order_date)
    245269    INTO v_busiest_day
     
    251275    LIMIT 1;
    252276
    253     -- Calculate completion rate
     277    -- Completion rate
    254278    v_completion_rate := CASE
    255279        WHEN v_total_orders > 0 THEN
     
    258282    END;
    259283
    260     -- Calculate orders per hour (during operating hours)
     284    -- Orders per hour (during operating hours)
    261285    WITH operating_hours AS (
    262         SELECT
    263             EXTRACT(EPOCH FROM (closing_time - opening_time))/3600 * 7 as total_hours_week
     286        SELECT EXTRACT(EPOCH FROM (closing_time - opening_time)) / 3600 * 7 AS total_hours_week
    264287        FROM restaurant
    265288        WHERE restaurant_id = p_restaurant_id
    266289    )
    267290    SELECT CASE
    268         WHEN oh.total_hours_week > 0 THEN v_total_orders::DECIMAL / oh.total_hours_week
    269         ELSE 0
    270     END
     291               WHEN oh.total_hours_week > 0
     292               THEN v_total_orders::DECIMAL / oh.total_hours_week
     293               ELSE 0
     294           END
    271295    INTO v_orders_per_hour
    272296    FROM operating_hours oh;
    273297
    274     -- Insert or update the weekly report
     298    -- Insert or update weekly report
    275299    INSERT INTO restaurant_weekly_report (
    276300        restaurant_id, report_week, week_number,
     
    302326        last_updated = CURRENT_TIMESTAMP;
    303327
    304     -- Generate popular items report
     328    -- Generate supporting reports
    305329    PERFORM generate_popular_items_report(p_restaurant_id, week_start);
    306 
    307     -- Generate daily breakdown
    308330    PERFORM generate_daily_breakdown_report(p_restaurant_id, week_start, week_end);
    309 
    310331END;
    311332$$ LANGUAGE plpgsql;
    312 
    313 == Popular Items Report Function
    314 CREATE OR REPLACE FUNCTION generate_popular_items_report(p_restaurant_id INT, p_week_start DATE)
    315     RETURNS void AS $$
     333}}}
     334\\
     335== Popular items report function
     336{{{#!sql
     337CREATE OR REPLACE FUNCTION generate_popular_items_report(
     338    p_restaurant_id INT,
     339    p_week_start DATE
     340)
     341RETURNS void AS $$
    316342BEGIN
    317343    -- Clear existing data for this week
    318344    DELETE FROM restaurant_popular_items
    319     WHERE restaurant_id = p_restaurant_id AND report_week = p_week_start;
    320 
    321     -- Insert top 10 popular items for the week
     345    WHERE restaurant_id = p_restaurant_id
     346      AND report_week = p_week_start;
     347
     348    -- Insert top 10 popular items
    322349    INSERT INTO restaurant_popular_items (
    323350        restaurant_id, report_week, item_id, item_name,
     
    327354        SELECT
    328355            i.item_id,
    329             i.name as item_name,
    330             COUNT(DISTINCT o.order_id) as times_ordered,
    331             SUM(oi.quantity) as total_quantity,
    332             SUM(oi.total_price) as total_revenue,
    333             AVG(oi.total_price / oi.quantity) as avg_price,
    334             ROW_NUMBER() OVER (ORDER BY COUNT(DISTINCT o.order_id) DESC) as popularity_rank
     356            i.name AS item_name,
     357            COUNT(DISTINCT o.order_id) AS times_ordered,
     358            SUM(oi.quantity) AS total_quantity,
     359            SUM(oi.total_price) AS total_revenue,
     360            AVG(oi.total_price / oi.quantity) AS avg_price,
     361            ROW_NUMBER() OVER (ORDER BY COUNT(DISTINCT o.order_id) DESC) AS popularity_rank
    335362        FROM orders o
    336             JOIN order_items oi ON o.order_id = oi.order_id
    337             JOIN item i ON oi.item_id = i.item_id
     363        JOIN order_items oi ON o.order_id = oi.order_id
     364        JOIN item i ON oi.item_id = i.item_id
    338365        WHERE o.restaurant_id = p_restaurant_id
    339366          AND o.order_date::date BETWEEN p_week_start AND p_week_start + INTERVAL '6 days'
     
    349376END;
    350377$$ LANGUAGE plpgsql;
    351 
    352 == Trend Analysis Function
     378}}}
     379\\
     380== Trend analysis function
     381{{{#!sql
    353382CREATE OR REPLACE FUNCTION generate_trend_analysis(p_restaurant_id INT)
    354     RETURNS void AS $$
     383RETURNS void AS $$
    355384DECLARE
    356385    week1_start DATE := get_week_start(CURRENT_DATE);
     
    374403BEGIN
    375404    -- Get weekly data
    376     SELECT gross_revenue, total_orders INTO w1_revenue, w1_orders
     405    SELECT gross_revenue, total_orders
     406    INTO w1_revenue, w1_orders
    377407    FROM restaurant_weekly_report
    378408    WHERE restaurant_id = p_restaurant_id AND report_week = week1_start;
    379409
    380     SELECT gross_revenue, total_orders INTO w2_revenue, w2_orders
     410    SELECT gross_revenue, total_orders
     411    INTO w2_revenue, w2_orders
    381412    FROM restaurant_weekly_report
    382413    WHERE restaurant_id = p_restaurant_id AND report_week = week2_start;
    383414
    384     SELECT gross_revenue, total_orders INTO w3_revenue, w3_orders
     415    SELECT gross_revenue, total_orders
     416    INTO w3_revenue, w3_orders
    385417    FROM restaurant_weekly_report
    386418    WHERE restaurant_id = p_restaurant_id AND report_week = week3_start;
    387419
    388     -- Calculate trends
     420    -- Growth calculations
    389421    IF w2_revenue > 0 THEN
    390422        revenue_growth := ROUND(((w1_revenue - w2_revenue) / w2_revenue) * 100, 2);
     
    399431    END IF;
    400432
    401     -- Determine trend direction
     433    -- Trend direction
    402434    revenue_trend_val := CASE
    403435        WHEN revenue_growth > 5 THEN 'INCREASING'
     
    412444    END;
    413445
    414     -- Generate alerts
     446    -- Alerts
    415447    IF revenue_growth < -20 THEN
    416         alerts := alerts || '{"type": "revenue_decline", "severity": "high", "message": "Revenue declined by more than 20% this week"}'::jsonb;
     448        alerts := alerts || '{"type":"revenue_decline","severity":"high","message":"Revenue declined by more than 20% this week"}'::jsonb;
    417449    END IF;
    418450
    419451    IF order_growth < -15 THEN
    420         alerts := alerts || '{"type": "order_decline", "severity": "medium", "message": "Order volume declined by more than 15% this week"}'::jsonb;
    421     END IF;
    422 
    423     -- Generate recommendations
     452        alerts := alerts || '{"type":"order_decline","severity":"medium","message":"Order volume declined by more than 15% this week"}'::jsonb;
     453    END IF;
     454
     455    -- Recommendations
    424456    IF revenue_trend_val = 'DECREASING' THEN
    425         recommendations := recommendations || '{"type": "marketing", "action": "Consider promotional campaigns or menu updates"}'::jsonb;
     457        recommendations := recommendations || '{"type":"marketing","action":"Consider promotional campaigns or menu updates"}'::jsonb;
    426458    END IF;
    427459
    428460    IF order_trend_val = 'DECREASING' THEN
    429         recommendations := recommendations || '{"type": "operations", "action": "Review menu pricing and delivery times"}'::jsonb;
    430     END IF;
    431 
    432     -- Insert trend analysis
     461        recommendations := recommendations || '{"type":"operations","action":"Review menu pricing and delivery times"}'::jsonb;
     462    END IF;
     463
     464    -- Insert or update
    433465    INSERT INTO restaurant_trend_analysis (
    434466        restaurant_id, week1_revenue, week2_revenue, week3_revenue,
     
    459491END;
    460492$$ LANGUAGE plpgsql;
     493}}}
     494\\
     495
     496
    461497
    462498= Trigger Functions
    463 == Update Restaurant Reports Trigger Function
     499== Trigger function to update reports when orders change
     500{{{#!sql
    464501CREATE OR REPLACE FUNCTION update_restaurant_reports()
    465     RETURNS TRIGGER AS $$
     502RETURNS TRIGGER AS $$
    466503DECLARE
    467504    affected_restaurant_id INT;
     
    476513        -- Update reports for the affected week
    477514        PERFORM generate_restaurant_weekly_report(affected_restaurant_id, order_date_to_check);
    478 
    479515        -- Update trend analysis
    480516        PERFORM generate_trend_analysis(affected_restaurant_id);
     
    493529END;
    494530$$ LANGUAGE plpgsql;
    495 
    496 == Update Reports on Items Change Trigger Function
     531}}}
     532
     533
     534\\
     535== Trigger function for order items changes
     536{{{#!sql
    497537CREATE OR REPLACE FUNCTION update_reports_on_items_change()
    498     RETURNS TRIGGER AS $$
     538RETURNS TRIGGER AS $$
    499539DECLARE
    500540    affected_restaurant_id INT;
     
    502542BEGIN
    503543    -- Get restaurant and date from the order
    504     SELECT restaurant_id, order_date::date INTO affected_restaurant_id, order_date_to_check
    505     FROM orders WHERE order_id = COALESCE(NEW.order_id, OLD.order_id);
     544    SELECT restaurant_id, order_date::date
     545    INTO affected_restaurant_id, order_date_to_check
     546    FROM orders
     547    WHERE order_id = COALESCE(NEW.order_id, OLD.order_id);
    506548
    507549    -- Only update if within the last 3 weeks
     
    514556END;
    515557$$ LANGUAGE plpgsql;
    516 
    517 == Create Triggers
     558}}}
     559\\
     560== Create triggers
     561{{{#!sql
    518562-- Trigger on orders table
    519563CREATE TRIGGER trg_update_restaurant_reports
    520     AFTER INSERT OR UPDATE OR DELETE ON orders
    521     FOR EACH ROW
     564AFTER INSERT OR UPDATE OR DELETE ON orders
     565FOR EACH ROW
    522566EXECUTE FUNCTION update_restaurant_reports();
    523567
    524568-- Trigger on order_items table
    525569CREATE TRIGGER trg_update_reports_items
    526     AFTER INSERT OR UPDATE OR DELETE ON order_items
    527     FOR EACH ROW
     570AFTER INSERT OR UPDATE OR DELETE ON order_items
     571FOR EACH ROW
    528572EXECUTE FUNCTION update_reports_on_items_change();
    529 
    530 == Report Views for Easy Access
    531 Comprehensive 3-Week Restaurant Report View
     573}}}
     574\\
     575== Report Views
     576{{{#!sql
     577-- Comprehensive 3-week restaurant report view
    532578CREATE VIEW restaurant_3week_summary AS
    533579SELECT
     
    540586    MAX(CASE WHEN rwr.week_number = 1 THEN rwr.completion_rate END) as current_week_completion_rate,
    541587
    542     -- Previous week (Week 2) 
     588    -- Previous week (Week 2)
    543589    MAX(CASE WHEN rwr.week_number = 2 THEN rwr.total_orders END) as prev_week_orders,
    544590    MAX(CASE WHEN rwr.week_number = 2 THEN rwr.gross_revenue END) as prev_week_revenue,
     
    558604    MAX(CASE WHEN rwr.week_number = 1 THEN rwr.busiest_day END) as current_busiest_day,
    559605    AVG(rwr.avg_preparation_time_minutes) as avg_prep_time,
    560 
    561606    MAX(rwr.last_updated) as last_updated
    562607FROM restaurant_weekly_report rwr
    563     JOIN restaurant r ON rwr.restaurant_id = r.restaurant_id
     608JOIN restaurant r ON rwr.restaurant_id = r.restaurant_id
    564609WHERE rwr.report_week >= CURRENT_DATE - INTERVAL '21 days'
    565610GROUP BY r.name, rwr.restaurant_id;
    566 
    567 == Top Performing Restaurants View
     611}}}
     612{{{#!sql
     613-- Top performing restaurants view
    568614CREATE VIEW top_restaurants_3weeks AS
    569615SELECT
     
    576622    rta.revenue_growth_rate
    577623FROM restaurant_weekly_report rwr
    578     JOIN restaurant r ON rwr.restaurant_id = r.restaurant_id
    579     LEFT JOIN restaurant_trend_analysis rta ON rwr.restaurant_id = rta.restaurant_id
     624JOIN restaurant r ON rwr.restaurant_id = r.restaurant_id
     625LEFT JOIN restaurant_trend_analysis rta ON rwr.restaurant_id = rta.restaurant_id
    580626WHERE rwr.report_week >= CURRENT_DATE - INTERVAL '21 days'
    581627GROUP BY r.name, rta.revenue_trend, rta.revenue_growth_rate
    582628ORDER BY total_revenue DESC;
    583 
    584 == Daily Reports Function
     629}}}
     630== Daily reports function
     631{{{#!sql
    585632CREATE OR REPLACE FUNCTION generate_daily_breakdown_report(
    586633    p_restaurant_id INT,
    587     p_week_start    DATE,
    588     p_week_end      DATE
     634    p_week_start DATE,
     635    p_week_end DATE
    589636) RETURNS void
    590     LANGUAGE plpgsql
     637LANGUAGE plpgsql
    591638AS $$
    592639DECLARE
    593     v_day              DATE := p_week_start;
    594     v_daily_orders     INTEGER := 0;
    595     v_daily_revenue    NUMERIC(12,2) := 0;
     640    v_day DATE := p_week_start;
     641    v_daily_orders INTEGER := 0;
     642    v_daily_revenue NUMERIC(12,2) := 0;
    596643    v_daily_items_sold INTEGER := 0;
    597     v_avg_order_value  NUMERIC(12,2) := 0;
    598     v_hourly_orders    JSONB := '{}'::jsonb;
     644    v_avg_order_value NUMERIC(12,2) := 0;
     645    v_hourly_orders JSONB := '{}'::jsonb;
    599646BEGIN
    600647    IF p_week_end < p_week_start THEN
     
    602649    END IF;
    603650
     651    -- Clear previous data
    604652    DELETE FROM restaurant_daily_breakdown
    605653    WHERE restaurant_id = p_restaurant_id
    606654      AND report_date BETWEEN p_week_start AND p_week_end;
    607655
     656    -- Loop through days
    608657    WHILE v_day <= p_week_end LOOP
    609658        -- Daily metrics
     
    622671        INTO v_daily_items_sold
    623672        FROM order_items oi
    624             JOIN orders o ON oi.order_id = o.order_id
     673        JOIN orders o ON oi.order_id = o.order_id
    625674        WHERE o.restaurant_id = p_restaurant_id
    626675          AND o.order_date::date = v_day
     
    663712
    664713        -- Next day
    665         v_day := v_day + 1;  -- date + integer yields date
     714        v_day := v_day + 1;
    666715    END LOOP;
    667716END;
    668717$$;
    669 
    670 == Constraint Addition
     718}}}
     719{{{#!sql
    671720ALTER TABLE restaurant_trend_analysis
    672     ADD CONSTRAINT uq_restaurant_id UNIQUE (restaurant_id);
     721ADD CONSTRAINT uq_restaurant_id UNIQUE (restaurant_id);
     722}}}
     723
     724
     725
     726
     727
     728
     729