DatabaseProgramming: functions.sql

File functions.sql, 7.5 KB (added by 231105, 13 days ago)
Line 
1-------------------------------FUNKCIJA 1 ---------------------------
2CREATE OR REPLACE FUNCTION free_seats_trip(
3 p_trip_id INT
4)
5RETURNS INT
6AS $$
7DECLARE
8 v_capacity INT;
9 v_sold_tickets INT;
10BEGIN
11 SELECT t.capacity
12 INTO v_capacity
13 FROM "Train Trip" tt
14 JOIN Train t
15 ON tt.Traintrain_id = t.train_id
16 WHERE tt.trip_id = p_trip_id;
17
18 SELECT COUNT(*)
19 INTO v_sold_tickets
20 FROM Ticket
21 WHERE "Train Triptrip_id" = p_trip_id;
22
23 RETURN v_capacity - v_sold_tickets;
24END;
25$$ LANGUAGE plpgsql;
26
27SELECT free_seats_trip(155);
28
29---------FUNKCIJA 1 Nina-----------
30
31CREATE OR REPLACE FUNCTION get_available_seats(p_trip_id INT)
32RETURNS INT AS $$
33DECLARE
34 v_capacity INT;
35 v_sold_tickets INT;
36BEGIN
37 SELECT t.capacity INTO v_capacity
38 FROM "Train Trip" tt
39 JOIN Train t ON tt.Traintrain_id = t.train_id
40 WHERE tt.trip_id = p_trip_id;
41
42 SELECT COUNT(*) INTO v_sold_tickets
43 FROM Ticket
44 WHERE "Train Triptrip_id" = p_trip_id;
45
46 RETURN v_capacity - v_sold_tickets;
47END;
48$$ LANGUAGE plpgsql;
49
50SELECT get_available_seats(345895);
51SELECT get_available_seats(155);
52
53
54----------FUNKCIJA 2 Nina----------------
55
56CREATE OR REPLACE FUNCTION get_trip_revenue_efficiency(p_trip_id INT)
57RETURNS TEXT AS $$
58DECLARE
59 v_capacity INT;
60 v_sold_count INT;
61 v_total_revenue NUMERIC;
62 v_occupancy_pct NUMERIC;
63 v_rev_per_seat NUMERIC;
64 v_result TEXT;
65BEGIN
66 SELECT t.capacity INTO v_capacity
67 FROM "Train Trip" tt
68 JOIN Train t ON tt.Traintrain_id = t.train_id
69 WHERE tt.trip_id = p_trip_id;
70
71 SELECT COUNT(*), COALESCE(SUM(price), 0)
72 INTO v_sold_count, v_total_revenue
73 FROM Ticket
74 WHERE "Train Triptrip_id" = p_trip_id;
75
76 IF v_capacity > 0 THEN
77 v_occupancy_pct := (v_sold_count::NUMERIC / v_capacity) * 100;
78 v_rev_per_seat := v_total_revenue / v_capacity;
79 ELSE
80 RETURN 'Error: Train has no capacity';
81 END IF;
82
83 IF v_occupancy_pct >= 85 THEN
84 v_result := 'High Demand (' || ROUND(v_occupancy_pct, 1) || '%)';
85 ELSIF v_occupancy_pct >= 50 THEN
86 v_result := 'Optimal (' || ROUND(v_occupancy_pct, 1) || '%)';
87 ELSE
88 v_result := 'Low Efficiency (' || ROUND(v_occupancy_pct, 1) || '%)';
89 END IF;
90
91 RETURN v_result || ' | Rev/Seat: ' || ROUND(v_rev_per_seat, 2);
92END;
93$$ LANGUAGE plpgsql;
94
95SELECT
96 tt.trip_id,
97 r.route_name,
98 tt.departure_time,
99 get_trip_revenue_efficiency(tt.trip_id) AS performance_report
100FROM "Train Trip" tt
101JOIN Route r ON tt.Routeroute_id = r.route_id
102WHERE tt.trip_status = 'Completed'
103ORDER BY tt.departure_time DESC
104LIMIT 150;
105
106
107-------FUNKCIJA 3 Nina--------------
108
109CREATE OR REPLACE FUNCTION get_passenger_name_by_id(p_id INT)
110RETURNS VARCHAR AS $$
111DECLARE
112 v_full_name VARCHAR;
113BEGIN
114 SELECT p.first_name || ' ' || p.last_name INTO v_full_name
115 FROM Passenger pass
116 JOIN Person p ON pass.PersonEMBG = p.EMBG
117 WHERE pass.passenger_id = p_id;
118
119 RETURN COALESCE(v_full_name, 'Passenger not found');
120END;
121$$ LANGUAGE plpgsql;
122
123SELECT get_passenger_name_by_id(500);
124
125----------- FUNKCIJA 4 Ana----------------
126
127CREATE OR REPLACE FUNCTION get_most_profitable_route()
128RETURNS TEXT AS $$
129DECLARE
130 v_route_name VARCHAR;
131 v_total_revenue NUMERIC;
132BEGIN
133 SELECT
134 r.route_name,
135 COALESCE(SUM(t.price), 0)
136 INTO
137 v_route_name,
138 v_total_revenue
139 FROM Route r
140 JOIN "Train Trip" tt
141 ON r.route_id = tt.Routeroute_id
142 JOIN Ticket t
143 ON tt.trip_id = t."Train Triptrip_id"
144 GROUP BY r.route_id, r.route_name
145 ORDER BY SUM(t.price) DESC
146 LIMIT 1;
147
148 RETURN
149 'Most Profitable Route: ' || v_route_name ||
150 ' | Total Revenue: ' || ROUND(v_total_revenue, 2);
151END;
152$$ LANGUAGE plpgsql;
153
154SELECT get_most_profitable_route();
155
156----------- FUNKCIJA 5 Ana----------------
157
158CREATE OR REPLACE FUNCTION check_frequent_traveler(p_passenger_id INT)
159RETURNS TEXT AS $$
160DECLARE
161 v_ticket_count INT;
162 v_full_name VARCHAR;
163BEGIN
164
165 SELECT p.first_name || ' ' || p.last_name
166 INTO v_full_name
167 FROM Passenger pass
168 JOIN Person p ON pass.PersonEMBG = p.EMBG
169 WHERE pass.passenger_id = p_passenger_id
170 LIMIT 1;
171
172 SELECT COUNT(t.ticket_id)
173 INTO v_ticket_count
174 FROM Ticket t
175 JOIN Payment pay ON t.Paymentpayment_id = pay.payment_id
176 JOIN Reservation r ON pay.Reservationreservation_id = r.reservation_id
177 WHERE r.Passengerpassenger_id = p_passenger_id;
178
179 IF v_ticket_count >= 20 THEN
180 RETURN v_full_name || ' is a VIP Frequent Traveler with ' || v_ticket_count || ' trips.';
181 ELSIF v_ticket_count >= 10 THEN
182 RETURN v_full_name || ' is a Frequent Traveler with ' || v_ticket_count || ' trips.';
183 ELSIF v_ticket_count > 0 THEN
184 RETURN v_full_name || ' is an Occasional Traveler with ' || v_ticket_count || ' trips.';
185 ELSE
186 RETURN v_full_name || ' has no trips.';
187 END IF;
188END;
189$$ LANGUAGE plpgsql;
190
191SELECT check_frequent_traveler(800);
192
193----------- FUNKCIJA 6 Ana ----------------
194
195CREATE OR REPLACE FUNCTION get_revenue_by_period(
196 p_start_date DATE,
197 p_end_date DATE
198)
199RETURNS TEXT AS $$
200DECLARE
201 v_total_tickets INT;
202 v_total_revenue NUMERIC;
203BEGIN
204 SELECT
205 COUNT(*),
206 COALESCE(SUM(t.price), 0)
207 INTO
208 v_total_tickets,
209 v_total_revenue
210 FROM Ticket t
211 JOIN "Train Trip" tt
212 ON t."Train Triptrip_id" = tt.trip_id
213 WHERE tt.departure_time::DATE
214 BETWEEN p_start_date AND p_end_date;
215
216 RETURN
217 'Period: ' || p_start_date || ' to ' || p_end_date ||
218 ' | Tickets Sold: ' || v_total_tickets ||
219 ' | Total Revenue: ' || ROUND(v_total_revenue, 2);
220END;
221$$ LANGUAGE plpgsql;
222
223SELECT get_revenue_by_period('2025-01-01', '2026-03-31');
224
225----------- FUNKCIJA 7 Marija ----------------
226
227CREATE FUNCTION get_passenger_total_spending(
228 p_embg CHAR(13)
229)
230RETURNS NUMERIC AS $$
231DECLARE
232 total_spending NUMERIC;
233BEGIN
234
235 SELECT COALESCE(SUM(pay.amount), 0)
236 INTO total_spending
237 FROM Payment pay
238 JOIN Passenger pas
239 ON pas.PersonEMBG = pay.PassengerPersonEMBG2
240 WHERE pas.PersonEMBG = p_embg;
241
242 RETURN total_spending;
243
244END;
245$$ LANGUAGE plpgsql;
246
247SELECT get_passenger_total_spending('2509982211077');
248
249----------- FUNKCIJA 8 Marija ----------------
250
251CREATE FUNCTION get_next_departing_trains()
252RETURNS TABLE (
253 trip_id INT,
254 train_id INT,
255 departure_time DATE,
256 arrival_time DATE,
257 trip_status VARCHAR
258)
259AS $$
260BEGIN
261
262 RETURN QUERY
263 SELECT
264 tt.trip_id,
265 tt.Traintrain_id,
266 tt.departure_time,
267 tt.arrival_time,
268 tt.trip_status
269 FROM "Train Trip" tt
270 WHERE tt.departure_time >= CURRENT_DATE
271 ORDER BY tt.departure_time ASC;
272
273END;
274$$ LANGUAGE plpgsql;
275
276SELECT * FROM get_next_departing_trains();
277
278----------- FUNKCIJA 9 Marija ----------------
279
280CREATE FUNCTION get_route_stations(
281 p_route_id INT
282)
283RETURNS TABLE (
284 sequence_number INT,
285 station_name VARCHAR,
286 city VARCHAR
287)
288AS $$
289BEGIN
290
291 RETURN QUERY
292 SELECT
293 rs.sequence_number,
294 st.station_name,
295 st.city
296 FROM Route_Segment rs
297 JOIN Station st
298 ON st.station_id = rs.Stationstation_id
299 WHERE rs.Routeroute_id = p_route_id
300 ORDER BY rs.sequence_number;
301
302END;
303$$ LANGUAGE plpgsql;
304
305SELECT * FROM get_route_stations(1);