DatabaseCreation: insert-tables-eventix.sql

File insert-tables-eventix.sql, 34.3 KB (added by 231070, 13 days ago)
Line 
1 ------------- INSERT во мали табели и INSERT на default вредности за поголеми табели -------------
2
3 -- SYSTEM / UNKNOWN USER
4INSERT INTO APP_USER (id, first_name, last_name, email, phone, created_at, user_password) VALUES (1, 'Unknown', 'User', 'unknown@system.com', '0000000', CURRENT_DATE, 'system');
5
6 -- STATUS
7INSERT INTO STATUS (status_name, description) VALUES ('CREATED', 'Order has been created, but not processed yet'), ('PAID', 'Order has been paid for in full and has been completed'), ('CANCELLED', 'Order has been cancelled, no payment has went through');
8
9 -- PAYMENT_METHOD
10INSERT INTO PAYMENT_METHOD (method_name) VALUES ('CASH'), ('CARD');
11
12 -- TICKET_TYPE
13INSERT INTO TICKET_TYPE (type_name) VALUES ('STANDARD'), ('VIP'), ('PARTER'), ('GENERAL_ADMISSION');
14
15 -- ROLES
16INSERT INTO ROLES (role_name) VALUES ('ADMINISTRATOR'), ('USER');
17
18 -- EVENT_ROLE
19INSERT INTO EVENT_ROLE (role_name) VALUES ('EVENT_ADMIN'), ('SALES_MANAGER'), ('INFO_ADMIN'), ('CONTENT_MANAGER');
20
21 -- CATEGORIZATION
22INSERT INTO categorization (category_name) VALUES ('Uncategorized'), ('Concerts'), ('Theatre'), ('Cinema'), ('Festivals'), ('Exhibitions'), ('Seminars');
23
24 -- SUBCATEGORY
25INSERT INTO SUBCATEGORY (subcategory_name, CATEGORIZATIONid)
26SELECT sub.subcategory_name, c.id
27FROM CATEGORIZATION c
28JOIN (VALUES
29 ('Concerts', 'Rock'),
30 ('Concerts', 'Pop'),
31 ('Concerts', 'Jazz'),
32 ('Concerts', 'Classical'),
33 ('Concerts', 'Electronic'),
34 ('Theatre', 'Drama'),
35 ('Theatre', 'Comedy'),
36 ('Theatre', 'Musical'),
37 ('Theatre', 'Opera'),
38 ('Cinema', 'Action'),
39 ('Cinema', 'Drama'),
40 ('Cinema', 'Horror'),
41 ('Cinema', 'Documentary'),
42 ('Festivals', 'Music'),
43 ('Festivals', 'Food'),
44 ('Festivals', 'Art'),
45 ('Festivals', 'Film'),
46 ('Exhibitions', 'Art'),
47 ('Exhibitions', 'Science'),
48 ('Exhibitions', 'History'),
49 ('Exhibitions', 'Technology'),
50 ('Seminars', 'Business'),
51 ('Seminars', 'Technology'),
52 ('Seminars', 'Health'),
53 ('Seminars', 'Education')
54) AS sub(cat_name, subcategory_name) ON c.category_name = sub.cat_name;
55
56
57
58 ------------------------------------ INSERT во табела APP_USER ------------------------------------ --
59
60DROP TABLE IF EXISTS temp_male_names, temp_female_names, surnames;
61CREATE TABLE temp_surnamesss (surname TEXT);
62WITH all_names AS (
63 SELECT DISTINCT name FROM temp_male_names
64 UNION
65 SELECT DISTINCT name FROM temp_female_names
66),
67surnames AS (
68 SELECT DISTINCT surname FROM temp_surnamesss
69)
70INSERT INTO app_user (first_name, last_name, email, phone, created_at, user_password)
71SELECT
72 n.name AS first_name,
73 s.surname AS last_name,
74
75 regexp_replace(n.name || '.' || s.surname, '[^A-Za-z0-9._%+-]', '', 'g')
76 || floor(random()*100000)::text || '@gmail.com' AS email,
77
78 (trunc(random() * 900000000) + 100000000)::text AS phone,
79
80 CURRENT_DATE - (trunc(random() * 3650))::int AS created_at,
81
82 n.name || s.surname AS user_password
83
84FROM all_names n
85CROSS JOIN surnames s
86ORDER BY random()
87LIMIT 50000;
88
89 ------------------------------------ INSERT во табела USER_ROLES ------------------------------------ --
90
91INSERT INTO user_roles (app_userid, rolesid)
92SELECT u.id, r.id
93FROM app_user u
94JOIN roles r ON r.role_name = 'USER'
95UNION ALL
96SELECT u.id, r.id
97FROM app_user u
98JOIN roles r ON r.role_name = 'ADMINISTRATOR'
99WHERE random() < 0.001;
100
101 ------------------------------------ INSERT во табела VENUE ------------------------------------ --
102
103-- Podatocite za iminja, ulici i gradovi se vnesuvaat od CSV fajlovi
104
105DROP TABLE IF EXISTS temp_venue_prefix, temp_venue_names, temp_street_names, temp_street_sufix, temp_cities;
106
107create TEMP TABLE temp_venue_prefix (name TEXT);
108create TEMP TABLE temp_venue_names (name TEXT);
109create TEMP TABLE temp_street_names (name TEXT);
110create TEMP TABLE temp_street_sufix (name TEXT);
111create TEMP TABLE temp_cities (name TEXT);
112
113\copy temp_venue_prefix(name) FROM 'D:\Downloads\prefix_venue.csv' DELIMITER ',' CSV HEADER;
114\copy temp_venue_names(name) FROM 'D:\Downloads\venue_name.csv' DELIMITER ',' CSV HEADER;
115\copy temp_street_names(name) FROM 'D:\Downloads\street_name.csv' DELIMITER ',' CSV HEADER;
116\copy temp_street_sufix(name) FROM 'D:\Downloads\street_sufix.csv' DELIMITER ',' CSV HEADER;
117\copy temp_cities(name) FROM 'D:\Downloads\cities.csv' DELIMITER ',' CSV HEADER;
118
119
120DROP TABLE IF EXISTS temp_venuess, temp_addreses;
121CREATE TEMP TABLE temp_venuess (id INT, venue TEXT);
122INSERT INTO temp_venuess (id, venue)
123SELECT row_number() OVER () AS id, venue
124FROM (
125 SELECT DISTINCT
126 CASE variant
127 WHEN 1 THEN vp.name || ' ' || vn.name
128 WHEN 2 THEN vp.name || ' ' || vn.name || ' I'
129 WHEN 3 THEN vp.name || ' ' || vn.name || ' II'
130 WHEN 4 THEN vp.name || ' ' || vn.name || ' III'
131 END AS venue
132 FROM temp_venue_prefix vp
133 CROSS JOIN temp_venue_names vn
134 CROSS JOIN generate_series(1, 4) AS variant
135) unique_names
136LIMIT 50000;
137
138 -- Адреси --
139CREATE TEMP TABLE temp_addreses (id INT, city TEXT, adress TEXT);
140
141INSERT INTO temp_addreses (id, city, adress)
142SELECT
143 row_number() OVER () AS id,
144 NULL AS city,
145 num::TEXT || ' ' || sn.name || ' ' || ss.name AS adress
146FROM temp_street_names sn
147CROSS JOIN temp_street_sufix ss
148CROSS JOIN generate_series(1, 99) AS num
149LIMIT 50000;
150
151 -- city --
152WITH addr AS (
153 select a.*, row_number() OVER () AS rn FROM temp_addreses a
154),
155cities AS (
156 select name, row_number() OVER () AS rn FROM temp_cities
157),
158cnt AS (
159 SELECT count(*) AS c FROM cities
160)
161UPDATE temp_addreses a
162SET city = c.name
163FROM addr ad
164JOIN cnt ON true
165JOIN cities c ON c.rn = ((ad.rn - 1) % cnt.c) + 1
166WHERE a.adress = ad.adress;
167
168DELETE FROM venue;
169INSERT INTO venue (venue_name, city, address)
170SELECT
171 LEFT(v.venue, 100) AS venue_name,
172 LEFT(a.city, 20) AS city,
173 LEFT(a.adress, 100) AS address
174FROM temp_venuess v
175JOIN temp_addreses a ON a.id = v.id;
176
177
178 ------------------------------------ INSERT во табела HALL ------------------------------------ --
179DROP TABLE IF EXISTS temp_hall_dist, temp_venue_numbered;
180
181CREATE TEMP TABLE temp_hall_dist (
182 r_from INT, r_to INT, n INT
183);
184INSERT INTO temp_hall_dist VALUES
185 ( 0, 44, 1), -- 45% imaat 1 hall
186 (45, 74, 2), -- 30% imaat 2 halls
187 (75, 89, 3), -- 15% imaat 3 halls
188 (90, 97, 4), -- 8% imaat 4 halls
189 (98, 99, 5); -- 2% imaat 5 halls
190
191CREATE TEMP TABLE temp_venue_numbered AS
192select id AS venue_id, (row_number() OVER (ORDER BY id) - 1) AS rn
193FROM venue;
194
195INSERT INTO hall (hall_name, capacity, venueid)
196select 'Hall ' || s AS hall_name,
197 CASE s
198 WHEN 1 THEN 30 + ((vn.rn * 7) % 271) -- max 300
199 WHEN 2 THEN 20 + ((vn.rn * 11) % 181) -- max 200
200 WHEN 3 THEN 15 + ((vn.rn * 13) % 136) -- max 150
201 WHEN 4 THEN 10 + ((vn.rn * 17) % 91) -- max 100
202 ELSE 10 + ((vn.rn * 19) % 91) -- max 100
203 END AS capacity,
204 vn.venue_id AS venueid
205FROM temp_venue_numbered vn
206JOIN temp_hall_dist d ON (vn.rn % 100) BETWEEN d.r_from AND d.r_to
207CROSS JOIN generate_series(1, d.n) AS s;
208
209
210-- ------------------------------------ INSERT во табела SEAT ------------------------------------ --
211
212-- Distribucija po tip:
213-- PARTER (tip 3): prvi 20% sedishta po sala
214-- STANDARD (tip 1): sredni 75% sedishta po sala
215-- VIP (tip 2): poslednite 5% sedishta po sala
216-- GENERAL_ADMISSION (tip 4): sali so kapacitet < 20
217-- Napomena: Poradi golemiot broj na redovi,
218-- se izvrshuvashe vo 4 batches po hall id range
219INSERT INTO SEAT (seat_number, HALLid, TICKET_TYPEid)
220select s.n AS seat_number, h.id AS HALLid,
221 CASE
222 WHEN s.n > h.capacity * 0.95 THEN 2 -- VIP ~5%
223 WHEN s.n <= h.capacity * 0.20 THEN 3 -- PARTER ~20%
224 ELSE 1 -- STANDARD ~75%
225 END AS TICKET_TYPEid
226FROM hall h
227CROSS JOIN LATERAL generate_series(1, h.capacity) AS s(n)
228WHERE h.capacity >= 20
229
230UNION ALL
231
232INSERT INTO SEAT (seat_number, HALLid, TICKET_TYPEid)
233SELECT 1, h.id, 4
234FROM hall h
235WHERE h.capacity < 20;
236
237 ------------------------------------ INSERT во табела PROMO_CODE ------------------------------------ --
238
239INSERT INTO PROMO_CODE (code, discount_percent, expiration_date, APP_USERid)
240select 'PROMO-' || gs.rn || '-' || upper(substr(md5(random()::TEXT), 1, 8)) AS code,
241
242 -- Realni popusti: 5, 10, 15, 20, 25, 30, 50
243 (ARRAY[5, 10, 15, 20, 25, 30, 50])[(random() * 6)::INT + 1] AS discount_percent,
244
245 -- 33% istecheni, 33% aktivni, 33% idni
246 CASE
247 WHEN gs.rn % 3 = 0 THEN CURRENT_DATE - (random() * 365)::INT
248 WHEN gs.rn % 3 = 1 THEN CURRENT_DATE + (random() * 365)::INT
249 ELSE CURRENT_DATE + (random() * 730)::INT
250 END AS expiration_date,
251
252 -- 20% imaat sopstvenik (user 2-50001), 80% se sistemski (default 1)
253 CASE
254 WHEN random() < 0.20 THEN (2 + (random() * 49999)::INT)
255 ELSE 1
256 END AS APP_USERid
257
258FROM generate_series(1, 10000) AS gs(rn);
259
260 ------------------------------------ INSERT во табела ORDER ------------------------------------ --
261
262INSERT INTO USER_ORDER (order_date, total_amount, APP_USERid, STATUSid, PROMO_CODEid)
263WITH
264 user_ids AS (SELECT id FROM APP_USER),
265 status_ids AS (SELECT id, status_name FROM STATUS),
266 promo_ids AS (SELECT id FROM PROMO_CODE),
267
268 user_arr AS (SELECT array_agg(id) AS arr FROM user_ids),
269 status_paid AS (SELECT id FROM STATUS WHERE status_name = 'PAID'),
270 status_created AS (SELECT id FROM STATUS WHERE status_name = 'CREATED'),
271 status_cancelled AS (SELECT id FROM STATUS WHERE status_name = 'CANCELLED'),
272 promo_arr AS (SELECT array_agg(id) AS arr FROM promo_ids)
273
274SELECT
275 -- Datumi: 70% minato, 20% idnina, 10% sega
276 CASE
277 WHEN (gs.rn % 10) < 7 THEN CURRENT_DATE - (random() * 1095)::INT
278 WHEN (gs.rn % 10) < 9 THEN CURRENT_DATE + (random() * 180)::INT
279 ELSE CURRENT_DATE - (random() * 7)::INT
280 END AS order_date,
281
282 -- Realen total_amount: 1-4 tiketi * realna cena
283 (1 + (random() * 3)::INT) *
284 (ARRAY[500,800,1000,1200,1500,2000,2500,3000])[(1 + (random() * 7)::INT)] AS total_amount,
285
286 -- APP_USERid od tabelata
287 (user_arr.arr)[(1 + (random() * (array_length(user_arr.arr, 1) - 1))::INT)] AS APP_USERid,
288
289 -- Status so realna raspredlba
290 CASE
291 WHEN random() < 0.60 THEN (SELECT id FROM status_paid)
292 WHEN random() < 0.85 THEN (SELECT id FROM status_created)
293 ELSE (SELECT id FROM status_cancelled)
294 END AS STATUSid,
295
296 -- 15% so promo code, 85% NULL
297 CASE
298 WHEN random() < 0.15 AND array_length(promo_arr.arr, 1) > 0
299 THEN (promo_arr.arr)[(1 + (random() * (array_length(promo_arr.arr, 1) - 1))::INT)]
300 ELSE NULL
301 END AS PROMO_CODEid
302
303FROM generate_series(1, 5000000) AS gs(rn)
304CROSS JOIN user_arr
305CROSS JOIN promo_arr;
306
307 ------------------------------------ INSERT во табела EVENT ------------------------------------ --
308
309-- Podatocite za naslovi i opisi se vnesuvaat od CSV fajlovi
310DROP TABLE IF EXISTS
311 temp_event_base, temp_event_suffix, temp_event_prefix,
312 temp_event_desc, temp_event_titles;
313
314CREATE TABLE temp_event_base (id BIGSERIAL PRIMARY KEY, name TEXT);
315CREATE TABLE temp_event_suffix (id BIGSERIAL PRIMARY KEY, name TEXT);
316CREATE TABLE temp_event_prefix (id BIGSERIAL PRIMARY KEY, name TEXT);
317CREATE TABLE temp_event_desc (id BIGSERIAL PRIMARY KEY, name TEXT);
318
319\copy temp_event_base(name) FROM 'D:\Downloads\event_base.csv' DELIMITER ',' CSV HEADER;
320\copy temp_event_suffix(name) FROM 'D:\Downloads\event_suffix.csv' DELIMITER ',' CSV HEADER;
321\copy temp_event_prefix(name) FROM 'D:\Downloads\event_prefix.csv' DELIMITER ',' CSV HEADER;
322\copy temp_event_desc(name) FROM 'D:\Downloads\event_desc.csv' DELIMITER ',' CSV HEADER;
323
324-- Kreiranje naslov
325-- Opcija 1: base + suffix "Rock Night 2025"
326-- Opcija 2: prefix + base + suffix "Annual Rock Night 2025"
327-- Vkupno: 556 * 95 * 2 = 105 640 unique titles
328
329drop table if exists temp_event_titles;
330CREATE TEMP TABLE temp_event_titles (id INT, title TEXT, cat_hint TEXT);
331
332INSERT INTO temp_event_titles (id, title, cat_hint)
333SELECT
334 row_number() OVER () AS id,
335 title,
336 -- Kategorija na nastanot da se bira spored kluchni zborovi vo naslovot
337 CASE
338 WHEN title ~* 'concert|music|jazz|rock|blues|soul|pop|band|singer|guitar|piano|violin|orchestra|symphon|recital|unplugged|acoustic|choir|opera gala'
339 THEN 'Concerts'
340 WHEN title ~* 'theatre|theater|drama|comedy show|musical|improv|stand.up|monologue|shakespeare|puppet|cabaret|burlesque|pantomime|circus|sketch'
341 THEN 'Theatre'
342 WHEN title ~* 'film|cinema|movie|screening|documentary|director|cineplex'
343 THEN 'Cinema'
344 WHEN title ~* 'festival|fest|fair|market|carnival|expo(?!sition)'
345 THEN 'Festivals'
346 WHEN title ~* 'exhibition|exhibit|gallery|sculpture|painting|installation|photo.*show|art show|retrospective|solo.*show|group.*show'
347 THEN 'Exhibitions'
348 WHEN title ~* 'seminar|workshop|conference|summit|forum|congress|symposium|bootcamp|masterclass|training|webinar|hackathon'
349 THEN 'Seminars'
350 ELSE NULL
351 END AS cat_hint
352FROM (
353 -- Prva opcija samo so osnova i sufiks
354 SELECT DISTINCT b.name || ' ' || s.name AS title
355 FROM temp_event_base b
356 CROSS JOIN temp_event_suffix s
357
358 UNION
359
360 -- Vtorata opcija prefiks pa osnova pa sufiks
361 SELECT DISTINCT p.name || ' ' || b.name || ' ' || s.name AS title
362 FROM temp_event_prefix p
363 CROSS JOIN temp_event_base b
364 CROSS JOIN temp_event_suffix s
365) unique_titles
366LIMIT 100000;
367
368-- Stavanje na categorizationid na nastanot cat_hint
369-- 1=Concerts, 2=Theatre, 3=Cinema, 4=Festivals, 5=Exhibitions, 6=Seminars
370
371-- Insert vo EVENT
372DELETE FROM event;
373INSERT INTO event (title, description, start_date, end_date, categorizationid)
374SELECT
375 LEFT(t.title, 50) AS title,
376
377 -- ~60% imaat opis a ~40% im e NULL
378 CASE
379 WHEN (t.id % 10) < 6
380 THEN (SELECT name
381 FROM temp_event_desc
382 WHERE temp_event_desc.id = (t.id % (SELECT max(id) FROM temp_event_desc)) + 1)
383 ELSE NULL
384 END
385 AS description,
386
387 -- start_date: ~55% stari (pochnati od 2022-01-01 do denes), ~45% idni (pochnati denes do 2027-12-31)
388 CASE
389 WHEN (t.id % 20) < 11
390 THEN DATE '2022-01-01' + ((t.id * 7 + 13) % 1186)
391 ELSE DATE '2025-05-01' + ((t.id * 11 + 7) % 974)
392 END
393 AS start_date,
394
395 -- end_date
396 CASE
397 -- Izlozhbi ~ 3–21 dena
398 WHEN t.cat_hint = 'Exhibitions'
399 THEN (CASE WHEN (t.id % 20) < 11
400 THEN DATE '2022-01-01' + ((t.id * 7 + 13) % 1186)
401 ELSE DATE '2025-05-01' + ((t.id * 11 + 7) % 974)
402 END) + ((t.id % 19) + 3)
403
404 -- Seminari ~ 1–5 dena
405 WHEN t.cat_hint = 'Seminars'
406 THEN (CASE WHEN (t.id % 20) < 11
407 THEN DATE '2022-01-01' + ((t.id * 7 + 13) % 1186)
408 ELSE DATE '2025-05-01' + ((t.id * 11 + 7) % 974)
409 END) + ((t.id % 5))
410
411 -- Festivali ~ 1–4 dena
412 WHEN t.cat_hint = 'Festivals'
413 THEN (CASE WHEN (t.id % 20) < 11
414 THEN DATE '2022-01-01' + ((t.id * 7 + 13) % 1186)
415 ELSE DATE '2025-05-01' + ((t.id * 11 + 7) % 974)
416 END) + ((t.id % 4))
417
418 -- Se drugo e tie shto traat eden den
419 ELSE (CASE WHEN (t.id % 20) < 11
420 THEN DATE '2022-01-01' + ((t.id * 7 + 13) % 1186)
421 ELSE DATE '2025-05-01' + ((t.id * 11 + 7) % 974)
422 END)
423 END
424 AS end_date,
425
426 -- categorizationid
427 CASE t.cat_hint
428 WHEN 'Concerts' THEN 1
429 WHEN 'Theatre' THEN 2
430 WHEN 'Cinema' THEN 3
431 WHEN 'Festivals' THEN 4
432 WHEN 'Exhibitions' THEN 5
433 WHEN 'Seminars' THEN 6
434 ELSE (t.id % 6) + 1
435 END
436 AS categorizationid
437
438FROM temp_event_titles t;
439
440-- subcategory dodavanje
441UPDATE event e
442SET subcategoryid = (
443 SELECT s.id
444 FROM subcategory s
445 WHERE s.categorizationid = e.categorizationid
446 ORDER BY random()
447 LIMIT 1
448)
449WHERE e.categorizationid != 1; -- Uncategorized nema subcategory
450
451
452
453
454-- ------------------------------------ INSERT во табела REVIEW ------------------------------------ --
455-- Rating distribucija: 5=35% 4=30% 3=20% 2=10% 1=5%
456-- Comment: 65% imaat komentar, 35% NULL
457-- app_userid: 85% imaat korisnik, 15% anonimni
458-- Napomena: Poradi golemiot broj na redovi, se izvrshuvaa vo batches po event_id range (25,000 nastani po batch)
459
460DROP TABLE IF EXISTS temp_ev, temp_usr, temp_comments;
461
462CREATE TEMP TABLE temp_ev AS
463SELECT id AS event_id, (row_number() OVER (ORDER BY id) - 1) AS rn
464FROM event;
465
466CREATE TEMP TABLE temp_usr AS
467SELECT id AS user_id, (row_number() OVER (ORDER BY id) - 1) AS rn
468FROM app_user;
469
470CREATE INDEX ON temp_ev(rn);
471CREATE INDEX ON temp_usr(rn);
472
473CREATE TEMP TABLE temp_comments (id SERIAL PRIMARY KEY, txt TEXT);
474
475\copy temp_comments(txt) FROM 'D:\Downloads\comments.csv' CSV HEADER;
476
477INSERT INTO review (rating, review_comment, app_userid, eventid)
478SELECT
479 CASE
480 WHEN ((e.rn * 31 + s * 17 + 3) % 100) < 35 THEN 5
481 WHEN ((e.rn * 31 + s * 17 + 3) % 100) < 65 THEN 4
482 WHEN ((e.rn * 31 + s * 17 + 3) % 100) < 85 THEN 3
483 WHEN ((e.rn * 31 + s * 17 + 3) % 100) < 95 THEN 2
484 ELSE 1
485 END AS rating,
486 CASE
487 WHEN ((e.rn * 13 + s * 7) % 100) < 65 THEN c.txt
488 ELSE NULL
489 END AS review_comment,
490 CASE
491 WHEN ((e.rn * 7 + s * 19) % 100) < 85 THEN u.user_id
492 ELSE NULL
493 END AS app_userid,
494 e.event_id AS eventid
495FROM temp_ev e
496CROSS JOIN LATERAL generate_series(1,
497 CASE
498 WHEN (e.rn % 100) < 10 THEN 20 + (e.rn % 21)
499 WHEN (e.rn % 100) < 60 THEN 60 + (e.rn % 61)
500 WHEN (e.rn % 100) < 90 THEN 120 + (e.rn % 61)
501 ELSE 180 + (e.rn % 71)
502 END
503) AS s
504JOIN temp_comments c
505 ON c.id = ((e.rn * 23 + s * 11) % 110) + 1
506LEFT JOIN temp_usr u
507 ON u.rn = ((e.rn * 41 + s * 13) % (SELECT max(rn) + 1 FROM temp_usr));
508
509DROP TABLE IF EXISTS temp_ev, temp_usr, temp_comments;
510
511-- Proverka
512SELECT count(*) AS total_reviews FROM review;
513SELECT rating, count(*) AS cnt,
514 round(count(*) * 100.0 / sum(count(*)) OVER (), 1) AS pct
515FROM review GROUP BY rating ORDER BY rating DESC;
516
517
518-- ------------------------------------ INSERT во табела ORDER ------------------------------------ --
519
520------------------------------
521INSERT INTO USER_ORDER (order_date, total_amount, APP_USERid, STATUSid, PROMO_CODEid)
522WITH
523 users AS (SELECT array_agg(id) AS uids, count(*)::INT AS cnt
524 FROM APP_USER WHERE id != 1),
525 status_ids AS (
526 SELECT
527 (SELECT id FROM STATUS WHERE status_name = 'PAID') AS paid_id,
528 (SELECT id FROM STATUS WHERE status_name = 'CREATED') AS created_id,
529 (SELECT id FROM STATUS WHERE status_name = 'CANCELLED') AS cancelled_id
530 ),
531 promo AS (SELECT array_agg(id) AS pids, count(*)::INT AS pcnt
532 FROM PROMO_CODE)
533SELECT
534 CASE
535 WHEN gs.rn % 10 < 7 THEN CURRENT_DATE - (random()*1095)::INT
536 WHEN gs.rn % 10 < 9 THEN CURRENT_DATE + (random()*180)::INT
537 ELSE CURRENT_DATE - (random()*7)::INT
538 END AS order_date,
539
540 (1 + (random()*3)::INT) *
541 (ARRAY[500,800,1000,1200,1500,2000,2500,3000])[(random()*7)::INT + 1] AS total_amount,
542
543 uids[(random()*(cnt-1))::INT + 1] AS APP_USERid,
544
545 CASE
546 WHEN random() < 0.60 THEN (SELECT paid_id FROM status_ids)
547 WHEN random() < 0.85 THEN (SELECT created_id FROM status_ids)
548 ELSE (SELECT cancelled_id FROM status_ids)
549 END AS STATUSid,
550
551 CASE
552 WHEN random() < 0.15 THEN pids[(random()*(pcnt-1))::INT + 1]
553 ELSE NULL
554 END AS PROMO_CODEid
555
556FROM generate_series(1, 5000000) AS gs(rn)
557CROSS JOIN users
558CROSS JOIN promo;
559
560-- Verifikacija
561SELECT count(*) AS total_orders FROM user_order;
562SELECT s.status_name, count(*) AS cnt,
563 round(count(*)*100.0/sum(count(*)) OVER(),1) AS pct
564FROM user_order uo
565JOIN status s ON s.id = uo.statusid
566GROUP BY s.status_name ORDER BY s.status_name;
567
568
569-- ------------------------------------ INSERT во табела WAITLIST ------------------------------------ --
570INSERT INTO WAITLIST (created_at, status, EVENTid)
571WITH
572 events AS (SELECT array_agg(id) AS eids, count(*)::INT AS cnt FROM EVENT)
573SELECT
574 CURRENT_DATE - (random()*365)::INT AS created_at,
575 CASE
576 WHEN random() < 0.50 THEN 'PENDING'
577 WHEN random() < 0.80 THEN 'CONFIRMED'
578 ELSE 'CANCELLED'
579 END AS status,
580 eids[(random()*(cnt-1))::INT + 1] AS EVENTid
581FROM generate_series(1, 10000) AS gs(rn)
582CROSS JOIN events;
583
584SELECT count(*) FROM waitlist;
585
586
587-- ------------------------------------ INSERT во табела EVENT_HALL (M:N) ------------------------------------ --
588
589INSERT INTO EVENT_HALL (EVENTid, HALLid, allowed_access)
590WITH
591 events AS (SELECT array_agg(id) AS eids, count(*)::INT AS ecnt FROM EVENT),
592 halls AS (SELECT array_agg(id) AS hids, count(*)::INT AS hcnt FROM HALL)
593SELECT DISTINCT ON (e_id, h_id)
594 e_id,
595 h_id,
596 random() < 0.70 AS allowed_access
597FROM (
598 SELECT
599 eids[(random()*(ecnt-1))::INT + 1] AS e_id,
600 hids[(random()*(hcnt-1))::INT + 1] AS h_id
601 FROM generate_series(1, 220000) gs -- 100k eventi * 2.2 prosechno
602 CROSS JOIN events
603 CROSS JOIN halls
604) sub;
605
606-- Proverka
607SELECT count(*) AS total FROM event_hall;
608SELECT avg(hall_count)::INT AS avg_hali_po_event
609FROM (SELECT eventid, count(*) AS hall_count FROM event_hall GROUP BY eventid) x;
610
611-- ------------------------------------ INSERT во табела EVENT_TICKET_TYPE (M:N) ------------------------------------ --
612
613INSERT INTO EVENT_TICKET_TYPE (EVENTid, TICKET_TYPEid, price, quantity_available)
614WITH
615 events AS (SELECT array_agg(id) AS eids, count(*)::INT AS ecnt FROM EVENT)
616SELECT DISTINCT ON (e_id, tt_id)
617 e_id,
618 tt_id,
619 CASE tt_id
620 WHEN 4 THEN (200 + (random() * 300)::INT)
621 WHEN 1 THEN (500 + (random() * 1000)::INT)
622 WHEN 3 THEN (1000 + (random() * 1500)::INT)
623 WHEN 2 THEN (2000 + (random() * 3000)::INT)
624 END AS price,
625 (50 + (random() * 950)::INT) AS quantity_available
626FROM (
627 SELECT
628 eids[(random()*(ecnt-1))::INT + 1] AS e_id,
629 unnest(
630 CASE
631 WHEN random() < 0.30 THEN ARRAY[1,2,3,4]
632 WHEN random() < 0.60 THEN ARRAY[1,3,4]
633 WHEN random() < 0.80 THEN ARRAY[1,2,3]
634 ELSE ARRAY[1,4]
635 END
636 ) AS tt_id
637 FROM generate_series(1, 120000) gs
638 CROSS JOIN events
639) sub;
640
641-- Verifikacija
642SELECT count(*) AS total FROM event_ticket_type;
643SELECT avg(tt_count)::INT AS avg_tipovi_po_event
644FROM (SELECT eventid, count(*) AS tt_count FROM event_ticket_type GROUP BY eventid) x;
645
646-- ------------------------------------ INSERT во табела EVENT_IMAGE ------------------------------------ --
647
648-- https://picsum.photos/seed/12345/800/600
649
650INSERT INTO EVENT_IMAGE (image_url, EVENTid)
651SELECT 'https://picsum.photos/seed/' || e.id+9 || '/800/600', e.id
652FROM event e;
653
654-- ------------------------------------ INSERT во табела USER_CATEGORY_SUBSCRIPTION ------------------------------------ --
655
656INSERT INTO USER_CATEGORY_SUBSCRIPTION (APP_USERid, CATEGORIZATIONid)
657SELECT DISTINCT ON (u.id, c.id)
658 u.id AS APP_USERid,
659 c.id AS CATEGORIZATIONid
660FROM (SELECT id FROM app_user WHERE id != 1 ORDER BY random() LIMIT 20000) u
661CROSS JOIN (SELECT id FROM categorization WHERE id != 1) c
662WHERE random() < 0.35;
663
664SELECT count(*) FROM user_category_subscription;
665
666
667-- ------------------------------- INSERT во табела USER_SUBCATEGORY_SUBSCRIPTION ------------------------------ --
668
669INSERT INTO USER_SUBCATEGORY_SUBSCRIPTION (APP_USERid, SUBCATEGORYid)
670SELECT DISTINCT ON (u.id, s.id)
671 u.id AS APP_USERid,
672 s.id AS SUBCATEGORYid
673FROM (SELECT id FROM app_user WHERE id != 1 ORDER BY random() LIMIT 50000) u
674CROSS JOIN (SELECT id FROM subcategory) s
675WHERE random() < 0.10;
676
677SELECT count(*) AS total FROM user_subcategory_subscription;
678
679
680-- ------------------------------- INSERT во табела TICKET ------------------------------ --
681
682-- Trgnati constraints za pobrzi inserti
683ALTER TABLE ticket DROP CONSTRAINT ticket_code_key;
684ALTER TABLE ticket DROP CONSTRAINT FK_ticket_ticket_type;
685ALTER TABLE ticket DROP CONSTRAINT FK_ticket_user_order;
686ALTER TABLE ticket DROP CONSTRAINT FK_ticket_user;
687ALTER TABLE ticket DROP CONSTRAINT FK_ticket_event;
688ALTER TABLE ticket DROP CONSTRAINT FK_ticket_hall;
689ALTER TABLE ticket DROP CONSTRAINT FK_ticket_seat;
690
691
692INSERT INTO TICKET (code, status, TICKET_TYPEid, USER_ORDERid, SEATid, APP_USERid, EVENTid, HALLid)
693WITH
694 valid_tickets AS (
695 SELECT
696 eh.eventid,
697 eh.hallid,
698 s.id AS seatid,
699 s.ticket_typeid,
700 ROW_NUMBER() OVER (PARTITION BY eh.eventid, eh.hallid ORDER BY s.id) AS rn,
701 h.capacity
702 FROM event_hall eh
703 JOIN hall h ON h.id = eh.hallid
704 JOIN seat s ON s.hallid = eh.hallid
705 ),
706 filtered AS (
707 SELECT vt.*
708 FROM valid_tickets vt
709 WHERE vt.rn <= vt.capacity
710 AND EXISTS (
711 SELECT 1 FROM event_ticket_type ett
712 WHERE ett.eventid = vt.eventid
713 AND ett.ticket_typeid = vt.ticket_typeid
714 )
715 LIMIT 10000000
716 ),
717 orders AS (
718 SELECT id, app_userid,
719 ROW_NUMBER() OVER (ORDER BY id) AS rn
720 FROM user_order
721 ),
722 total_orders AS (SELECT count(*)::INT AS cnt FROM user_order)
723SELECT
724 'TKT-' || row_number() OVER () AS code,
725 CASE WHEN random() < 0.70 THEN 'ACTIVE'
726 WHEN random() < 0.90 THEN 'USED'
727 ELSE 'CANCELLED'
728 END AS status,
729 f.ticket_typeid,
730 o.id AS user_orderid,
731 f.seatid,
732 o.app_userid,
733 f.eventid,
734 f.hallid
735FROM filtered f
736JOIN orders o ON o.rn = ((f.rn - 1) % (SELECT cnt FROM total_orders)) + 1;
737
738SELECT count(*) AS total_tickets FROM ticket;
739
740
741
742
743-- proverki
744
745-- 1. Vkupno po status
746SELECT status, count(*) AS cnt,
747 round(count(*)*100.0/sum(count(*)) OVER(),1) AS pct
748FROM ticket GROUP BY status ORDER BY status;
749
750-- 2. Dali ima ticket so hall koj ne e vo event_hall za toj event
751SELECT count(*) AS hall_ne_e_vo_event
752FROM ticket t
753WHERE NOT EXISTS (
754 SELECT 1 FROM event_hall eh
755 WHERE eh.eventid = t.eventid
756 AND eh.hallid = t.hallid
757);
758
759-- 3. Dali ima ticket so tip koj ne postoi vo event_ticket_type
760SELECT count(*) AS tip_ne_e_vo_event
761FROM ticket t
762WHERE NOT EXISTS (
763 SELECT 1 FROM event_ticket_type ett
764 WHERE ett.eventid = t.eventid
765 AND ett.ticket_typeid = t.ticket_typeid
766);
767
768
769-- 4. Dali ima duplikati seat+event
770SELECT count(*) AS duplikati_seat_event
771FROM (
772 SELECT seatid, eventid
773 FROM ticket
774 WHERE seatid IS NOT NULL
775 GROUP BY seatid, eventid
776 HAVING count(*) > 1
777) x;
778
779
780-- 5. Dali app_userid e konzistenten so user_orderid
781SELECT count(*) AS pogreshen_user
782FROM ticket t
783JOIN user_order uo ON uo.id = t.user_orderid
784WHERE uo.app_userid != t.app_userid;
785
786-- 6. Dali ima GA tiketi so seat
787SELECT count(*) AS ga_so_seat
788FROM ticket
789WHERE ticket_typeid = 4
790 AND seatid IS NOT NULL;
791
792-- Finalna statistika
793SELECT
794 count(*) AS vkupno_tiketi,
795 count(*) FILTER (WHERE seatid IS NOT NULL) AS so_seat,
796 count(*) FILTER (WHERE seatid IS NULL) AS bez_seat,
797 count(*) FILTER (WHERE status = 'ACTIVE') AS active,
798 count(*) FILTER (WHERE status = 'USED') AS used,
799 count(*) FILTER (WHERE status = 'CANCELLED') AS cancelled
800FROM ticket;
801
802-- Vrateni constraints
803ALTER TABLE ticket ADD CONSTRAINT ticket_code_key UNIQUE (code);
804ALTER TABLE ticket ADD CONSTRAINT FK_ticket_ticket_type
805 FOREIGN KEY (TICKET_TYPEid) REFERENCES TICKET_TYPE(id);
806ALTER TABLE ticket ADD CONSTRAINT FK_ticket_user_order
807 FOREIGN KEY (USER_ORDERid) REFERENCES USER_ORDER(id);
808ALTER TABLE ticket ADD CONSTRAINT FK_ticket_user
809 FOREIGN KEY (APP_USERid) REFERENCES APP_USER(id);
810ALTER TABLE ticket ADD CONSTRAINT FK_ticket_event
811 FOREIGN KEY (EVENTid) REFERENCES EVENT(id);
812ALTER TABLE ticket ADD CONSTRAINT FK_ticket_hall
813 FOREIGN KEY (HALLid) REFERENCES HALL(id);
814ALTER TABLE ticket ADD CONSTRAINT FK_ticket_seat
815 FOREIGN KEY (SEATid) REFERENCES SEAT(id);
816
817-- ------------------------------------ INSERT во табела PAYMENT ------------------------------------ --
818
819INSERT INTO PAYMENT (amount, status, payment_date, USER_ORDERid, PAYMENT_METHODid)
820SELECT
821 uo.total_amount AS amount,
822
823 CASE s.status_name
824 WHEN 'PAID' THEN 'COMPLETED'
825 WHEN 'CANCELLED' THEN (CASE WHEN random() < 0.5 THEN 'FAILED' ELSE 'COMPLETED' END)
826 WHEN 'CREATED' THEN (CASE WHEN random() < 0.7 THEN 'PENDING' ELSE 'COMPLETED' END)
827 END AS status,
828
829 uo.order_date + (random() * 2)::INT AS payment_date,
830
831 uo.id AS user_orderid,
832
833 CASE WHEN random() < 0.30 THEN 1 ELSE 2 END AS payment_methodid
834
835FROM user_order uo
836JOIN status s ON s.id = uo.statusid;
837
838SELECT count(*) AS total_payments FROM payment;
839SELECT status, count(*) AS cnt,
840 round(count(*)*100.0/sum(count(*)) OVER(),1) AS pct
841FROM payment GROUP BY status ORDER BY status;
842
843
844-- ------------------------------------ INSERT во табела REFUND ------------------------------------ --
845
846INSERT INTO REFUND (amount, reason, status, PAYMENTid)
847SELECT
848 CASE
849 WHEN random() < 0.60 THEN p.amount
850 ELSE 0
851 END AS amount,
852
853 (ARRAY[
854 'Event cancelled by organizer',
855 'Duplicate payment',
856 'Customer request',
857 'Technical error during purchase',
858 'Event rescheduled',
859 'Venue capacity issue',
860 'Medical emergency',
861 'Unable to attend'
862 ])[(random()*7)::INT + 1] AS reason,
863
864 CASE
865 WHEN random() < 0.60 THEN 'APPROVED'
866 WHEN random() < 0.85 THEN 'REQUESTED'
867 ELSE 'REJECTED'
868 END AS status,
869
870 p.id AS PAYMENTid
871
872FROM (SELECT id, amount FROM payment WHERE status = 'COMPLETED' LIMIT 50000) p;
873
874SELECT count(*) AS total_refunds FROM refund;
875SELECT status, count(*) AS cnt, round(count(*)*100.0/sum(count(*)) OVER(),1) AS pct
876FROM refund GROUP BY status ORDER BY status;
877
878-- ------------------------------------ INSERT во табела NOTIFICATION ------------------------------------ --
879INSERT INTO NOTIFICATION (message, created_at, APP_USERid)
880SELECT
881 (ARRAY[
882 'Your ticket has been confirmed.',
883 'New event available in your subscribed category.',
884 'Your order has been successfully paid.',
885 'Reminder: Your event starts tomorrow.',
886 'Your refund has been approved.',
887 'A new promo code is available for you.',
888 'Event you liked has new available seats.',
889 'Your review has been published.',
890 'Order cancellation confirmed.',
891 'New events added near your location.',
892 'Your waitlist request has been confirmed.',
893 'Payment failed. Please try again.',
894 'New event added in your city.',
895 'Your ticket has been cancelled.',
896 'Upcoming event reminder: starts in 3 days.'
897 ])[(random()*14)::INT + 1] AS message,
898
899 CURRENT_DATE - (random()*730)::INT AS created_at,
900
901 (SELECT id FROM app_user WHERE id != 1
902 ORDER BY random() LIMIT 1) AS APP_USERid
903
904FROM generate_series(1, 1000000) gs;
905
906
907-- ------------------------------------ INSERT во табела USER_EVENT ------------------------------------ --
908INSERT INTO USER_EVENT (APP_USERid, EVENTid, EVENT_ROLEid)
909SELECT DISTINCT ON (u.id, e.id)
910 u.id AS APP_USERid,
911 e.id AS EVENTid,
912 CASE
913 WHEN random() < 0.10 THEN 1 -- EVENT_ADMIN
914 WHEN random() < 0.30 THEN 2 -- SALES_MANAGER
915 WHEN random() < 0.60 THEN 3 -- INFO_ADMIN
916 ELSE 4 -- CONTENT_MANAGER
917 END AS EVENT_ROLEid
918FROM (SELECT id FROM app_user WHERE id != 1 ORDER BY random() LIMIT 5000) u
919CROSS JOIN (SELECT id FROM event ORDER BY random() LIMIT 5000) e
920WHERE random() < 0.015;
921
922SELECT count(*) AS total FROM user_event;
923SELECT er.role_name, count(*) AS cnt,
924 round(count(*)*100.0/sum(count(*)) OVER(),1) AS pct
925FROM user_event ue
926JOIN event_role er ON er.id = ue.event_roleid
927GROUP BY er.role_name
928ORDER BY er.role_name;
929
930-- ------------------------------- INSERT во табела USER_WAITLIST ------------------------------ --
931
932TRUNCATE TABLE user_waitlist;
933
934INSERT INTO USER_WAITLIST (APP_USERid, WAITLISTid)
935SELECT
936 u.id AS APP_USERid,
937 w.id AS WAITLISTid
938FROM waitlist w
939JOIN (
940 SELECT id, row_number() OVER (ORDER BY random()) AS rn
941 FROM app_user WHERE id != 1
942) u ON u.rn = (w.id % 50000) + 1;
943
944SELECT count(*) FROM user_waitlist;
945
946-- ------------------------------- INSERT во табела REFUND ------------------------------ --
947
948INSERT INTO REFUND (amount, reason, status, PAYMENTid)
949SELECT
950 CASE
951 WHEN random() < 0.60 THEN p.amount
952 ELSE 0
953 END AS amount,
954
955 (ARRAY[
956 'Event cancelled by organizer',
957 'Duplicate payment',
958 'Customer request',
959 'Technical error during purchase',
960 'Event rescheduled',
961 'Venue capacity issue',
962 'Medical emergency',
963 'Unable to attend'
964 ])[(random()*7)::INT + 1] AS reason,
965
966 CASE
967 WHEN random() < 0.60 THEN 'APPROVED'
968 WHEN random() < 0.85 THEN 'REQUESTED'
969 ELSE 'REJECTED'
970 END AS status,
971
972 p.id AS PAYMENTid
973
974FROM (SELECT id, amount FROM payment WHERE status = 'COMPLETED' LIMIT 50000) p;
975
976SELECT count(*) AS total_refunds FROM refund;
977SELECT status, count(*) AS cnt,
978 round(count(*)*100.0/sum(count(*)) OVER(),1) AS pct
979FROM refund GROUP BY status ORDER BY status;