DatabaseCreation: insert-tables-final.sql

File insert-tables-final.sql, 31.3 KB (added by 231070, 6 hours 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-- PROMO-1-A3B4C5D6
242
243 -- Realni popusti: 5, 10, 15, 20, 25, 30, 50
244 (ARRAY[5, 10, 15, 20, 25, 30, 50])[(random() * 6)::INT + 1] AS discount_percent,
245
246 -- 33% istecheni, 33% aktivni, 33% idni
247 CASE
248 WHEN gs.rn % 3 = 0 THEN CURRENT_DATE - (random() * 365)::INT
249 WHEN gs.rn % 3 = 1 THEN CURRENT_DATE + (random() * 365)::INT
250 ELSE CURRENT_DATE + (random() * 730)::INT
251 END AS expiration_date,
252
253 -- 20% imaat sopstvenik (user 2-50001), 80% se sistemski (default 1)
254 CASE
255 WHEN random() < 0.20 THEN (2 + (random() * 49999)::INT)
256 ELSE 1
257 END AS APP_USERid
258
259FROM generate_series(1, 10000) AS gs(rn);
260
261 ------------------------------------ INSERT во табела ORDER ------------------------------------ --
262
263INSERT INTO USER_ORDER (order_date, total_amount, APP_USERid, STATUSid, PROMO_CODEid)
264WITH
265 user_ids AS (SELECT id FROM APP_USER),
266 status_ids AS (SELECT id, status_name FROM STATUS),
267 promo_ids AS (SELECT id FROM PROMO_CODE),
268
269 user_arr AS (SELECT array_agg(id) AS arr FROM user_ids),
270 status_paid AS (SELECT id FROM STATUS WHERE status_name = 'PAID'),
271 status_created AS (SELECT id FROM STATUS WHERE status_name = 'CREATED'),
272 status_cancelled AS (SELECT id FROM STATUS WHERE status_name = 'CANCELLED'),
273 promo_arr AS (SELECT array_agg(id) AS arr FROM promo_ids)
274
275SELECT
276 -- Datumi: 90% minato, 10% sega
277 CASE
278 WHEN (gs.rn % 10) < 9 THEN CURRENT_DATE - (random() * 1095)::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 во табела WAITLIST ------------------------------------ --
519INSERT INTO WAITLIST (created_at, status, EVENTid)
520WITH
521 events AS (SELECT array_agg(id) AS eids, count(*)::INT AS cnt FROM EVENT)
522SELECT
523 CURRENT_DATE - (random()*365)::INT AS created_at,
524 CASE
525 WHEN random() < 0.50 THEN 'PENDING'
526 WHEN random() < 0.80 THEN 'CONFIRMED'
527 ELSE 'CANCELLED'
528 END AS status,
529 eids[(random()*(cnt-1))::INT + 1] AS EVENTid
530FROM generate_series(1, 10000) AS gs(rn)
531CROSS JOIN events;
532
533SELECT count(*) FROM waitlist;
534
535
536-- ------------------------------------ INSERT во табела EVENT_HALL (M:N) ------------------------------------ --
537
538INSERT INTO EVENT_HALL (EVENTid, HALLid, allowed_access)
539WITH
540 events AS (SELECT array_agg(id) AS eids, count(*)::INT AS ecnt FROM EVENT),
541 halls AS (SELECT array_agg(id) AS hids, count(*)::INT AS hcnt FROM HALL)
542SELECT DISTINCT ON (e_id, h_id)
543 e_id,
544 h_id,
545 random() < 0.70 AS allowed_access
546FROM (
547 SELECT
548 eids[(random()*(ecnt-1))::INT + 1] AS e_id,
549 hids[(random()*(hcnt-1))::INT + 1] AS h_id
550 FROM generate_series(1, 220000) gs -- 100k eventi * 2.2 prosechno
551 CROSS JOIN events
552 CROSS JOIN halls
553) sub;
554
555-- Proverka
556SELECT count(*) AS total FROM event_hall;
557SELECT avg(hall_count)::INT AS avg_hali_po_event
558FROM (SELECT eventid, count(*) AS hall_count FROM event_hall GROUP BY eventid) x;
559
560-- ------------------------------------ INSERT во табела EVENT_TICKET_TYPE (M:N) ------------------------------------ --
561
562INSERT INTO EVENT_TICKET_TYPE (EVENTid, TICKET_TYPEid, price, quantity_available)
563WITH
564 events AS (SELECT array_agg(id) AS eids, count(*)::INT AS ecnt FROM EVENT)
565SELECT DISTINCT ON (e_id, tt_id)
566 e_id,
567 tt_id,
568 CASE tt_id
569 WHEN 4 THEN (200 + (random() * 300)::INT)
570 WHEN 1 THEN (500 + (random() * 1000)::INT)
571 WHEN 3 THEN (1000 + (random() * 1500)::INT)
572 WHEN 2 THEN (2000 + (random() * 3000)::INT)
573 END AS price,
574 (50 + (random() * 950)::INT) AS quantity_available
575FROM (
576 SELECT
577 eids[(random()*(ecnt-1))::INT + 1] AS e_id,
578 unnest(
579 CASE
580 WHEN random() < 0.30 THEN ARRAY[1,2,3,4]
581 WHEN random() < 0.60 THEN ARRAY[1,3,4]
582 WHEN random() < 0.80 THEN ARRAY[1,2,3]
583 ELSE ARRAY[1,4]
584 END
585 ) AS tt_id
586 FROM generate_series(1, 120000) gs
587 CROSS JOIN events
588) sub;
589
590-- Verifikacija
591SELECT count(*) AS total FROM event_ticket_type;
592SELECT avg(tt_count)::INT AS avg_tipovi_po_event
593FROM (SELECT eventid, count(*) AS tt_count FROM event_ticket_type GROUP BY eventid) x;
594
595-- ------------------------------------ INSERT во табела EVENT_IMAGE ------------------------------------ --
596
597-- https://picsum.photos/seed/12345/800/600
598
599INSERT INTO EVENT_IMAGE (image_url, EVENTid)
600SELECT 'https://picsum.photos/seed/' || e.id+9 || '/800/600', e.id
601FROM event e;
602
603-- ------------------------------------ INSERT во табела USER_CATEGORY_SUBSCRIPTION ------------------------------------ --
604
605INSERT INTO USER_CATEGORY_SUBSCRIPTION (APP_USERid, CATEGORIZATIONid)
606SELECT DISTINCT ON (u.id, c.id)
607 u.id AS APP_USERid,
608 c.id AS CATEGORIZATIONid
609FROM (SELECT id FROM app_user WHERE id != 1 ORDER BY random() LIMIT 20000) u
610CROSS JOIN (SELECT id FROM categorization WHERE id != 1) c
611WHERE random() < 0.35;
612
613SELECT count(*) FROM user_category_subscription;
614
615
616-- ------------------------------- INSERT во табела USER_SUBCATEGORY_SUBSCRIPTION ------------------------------ --
617
618INSERT INTO USER_SUBCATEGORY_SUBSCRIPTION (APP_USERid, SUBCATEGORYid)
619SELECT DISTINCT ON (u.id, s.id)
620 u.id AS APP_USERid,
621 s.id AS SUBCATEGORYid
622FROM (SELECT id FROM app_user WHERE id != 1 ORDER BY random() LIMIT 50000) u
623CROSS JOIN (SELECT id FROM subcategory) s
624WHERE random() < 0.10;
625
626SELECT count(*) AS total FROM user_subcategory_subscription;
627
628
629-- ------------------------------- INSERT во табела TICKET ------------------------------ --
630
631-- Trgnati constraints za pobrzi inserti
632ALTER TABLE ticket DROP CONSTRAINT ticket_code_key;
633ALTER TABLE ticket DROP CONSTRAINT FK_ticket_ticket_type;
634ALTER TABLE ticket DROP CONSTRAINT FK_ticket_user_order;
635ALTER TABLE ticket DROP CONSTRAINT FK_ticket_user;
636ALTER TABLE ticket DROP CONSTRAINT FK_ticket_event;
637ALTER TABLE ticket DROP CONSTRAINT FK_ticket_hall;
638ALTER TABLE ticket DROP CONSTRAINT FK_ticket_seat;
639
640
641INSERT INTO TICKET (code, status, TICKET_TYPEid, USER_ORDERid, SEATid, APP_USERid, EVENTid, HALLid)
642WITH
643 valid_tickets AS (
644 SELECT
645 eh.eventid,
646 eh.hallid,
647 s.id AS seatid,
648 s.ticket_typeid,
649 ROW_NUMBER() OVER (PARTITION BY eh.eventid, eh.hallid ORDER BY s.id) AS rn,
650 h.capacity
651 FROM event_hall eh
652 JOIN hall h ON h.id = eh.hallid
653 JOIN seat s ON s.hallid = eh.hallid
654 ),
655 filtered AS (
656 SELECT vt.*
657 FROM valid_tickets vt
658 WHERE vt.rn <= vt.capacity
659 AND EXISTS (
660 SELECT 1 FROM event_ticket_type ett
661 WHERE ett.eventid = vt.eventid
662 AND ett.ticket_typeid = vt.ticket_typeid
663 )
664 LIMIT 10000000
665 ),
666 orders AS (
667 SELECT id, app_userid,
668 ROW_NUMBER() OVER (ORDER BY id) AS rn
669 FROM user_order
670 ),
671 total_orders AS (SELECT count(*)::INT AS cnt FROM user_order)
672SELECT
673 'TKT-' || row_number() OVER () AS code,
674 CASE WHEN random() < 0.70 THEN 'ACTIVE'
675 WHEN random() < 0.90 THEN 'USED'
676 ELSE 'CANCELLED'
677 END AS status,
678 f.ticket_typeid,
679 o.id AS user_orderid,
680 f.seatid,
681 o.app_userid,
682 f.eventid,
683 f.hallid
684FROM filtered f
685JOIN orders o ON o.rn = ((f.rn - 1) % (SELECT cnt FROM total_orders)) + 1;
686
687SELECT count(*) AS total_tickets FROM ticket;
688
689
690
691
692-- proverki
693
694-- 1. Vkupno po status
695SELECT status, count(*) AS cnt,
696 round(count(*)*100.0/sum(count(*)) OVER(),1) AS pct
697FROM ticket GROUP BY status ORDER BY status;
698
699-- 2. Dali ima ticket so hall koj ne e vo event_hall za toj event
700SELECT count(*) AS hall_ne_e_vo_event
701FROM ticket t
702WHERE NOT EXISTS (
703 SELECT 1 FROM event_hall eh
704 WHERE eh.eventid = t.eventid
705 AND eh.hallid = t.hallid
706);
707
708-- 3. Dali ima ticket so tip koj ne postoi vo event_ticket_type
709SELECT count(*) AS tip_ne_e_vo_event
710FROM ticket t
711WHERE NOT EXISTS (
712 SELECT 1 FROM event_ticket_type ett
713 WHERE ett.eventid = t.eventid
714 AND ett.ticket_typeid = t.ticket_typeid
715);
716
717
718-- 4. Dali ima duplikati seat+event
719SELECT count(*) AS duplikati_seat_event
720FROM (
721 SELECT seatid, eventid
722 FROM ticket
723 WHERE seatid IS NOT NULL
724 GROUP BY seatid, eventid
725 HAVING count(*) > 1
726) x;
727
728
729-- 5. Dali app_userid e konzistenten so user_orderid
730SELECT count(*) AS pogreshen_user
731FROM ticket t
732JOIN user_order uo ON uo.id = t.user_orderid
733WHERE uo.app_userid != t.app_userid;
734
735-- 6. Dali ima GA tiketi so seat
736SELECT count(*) AS ga_so_seat
737FROM ticket
738WHERE ticket_typeid = 4
739 AND seatid IS NOT NULL;
740
741-- Finalna statistika
742SELECT
743 count(*) AS vkupno_tiketi,
744 count(*) FILTER (WHERE seatid IS NOT NULL) AS so_seat,
745 count(*) FILTER (WHERE seatid IS NULL) AS bez_seat,
746 count(*) FILTER (WHERE status = 'ACTIVE') AS active,
747 count(*) FILTER (WHERE status = 'USED') AS used,
748 count(*) FILTER (WHERE status = 'CANCELLED') AS cancelled
749FROM ticket;
750
751-- Vrateni constraints
752ALTER TABLE ticket ADD CONSTRAINT ticket_code_key UNIQUE (code);
753ALTER TABLE ticket ADD CONSTRAINT FK_ticket_ticket_type
754 FOREIGN KEY (TICKET_TYPEid) REFERENCES TICKET_TYPE(id);
755ALTER TABLE ticket ADD CONSTRAINT FK_ticket_user_order
756 FOREIGN KEY (USER_ORDERid) REFERENCES USER_ORDER(id);
757ALTER TABLE ticket ADD CONSTRAINT FK_ticket_user
758 FOREIGN KEY (APP_USERid) REFERENCES APP_USER(id);
759ALTER TABLE ticket ADD CONSTRAINT FK_ticket_event
760 FOREIGN KEY (EVENTid) REFERENCES EVENT(id);
761ALTER TABLE ticket ADD CONSTRAINT FK_ticket_hall
762 FOREIGN KEY (HALLid) REFERENCES HALL(id);
763ALTER TABLE ticket ADD CONSTRAINT FK_ticket_seat
764 FOREIGN KEY (SEATid) REFERENCES SEAT(id);
765
766-- ------------------------------------ INSERT во табела PAYMENT ------------------------------------ --
767
768INSERT INTO PAYMENT (amount, status, payment_date, USER_ORDERid, PAYMENT_METHODid)
769SELECT
770 uo.total_amount AS amount,
771
772 CASE s.status_name
773 WHEN 'PAID' THEN 'COMPLETED'
774 WHEN 'CANCELLED' THEN (CASE WHEN random() < 0.5 THEN 'FAILED' ELSE 'COMPLETED' END)
775 WHEN 'CREATED' THEN (CASE WHEN random() < 0.7 THEN 'PENDING' ELSE 'COMPLETED' END)
776 END AS status,
777
778 uo.order_date + (random() * 2)::INT AS payment_date,
779
780 uo.id AS user_orderid,
781
782 CASE WHEN random() < 0.30 THEN 1 ELSE 2 END AS payment_methodid
783
784FROM user_order uo
785JOIN status s ON s.id = uo.statusid;
786
787SELECT count(*) AS total_payments FROM payment;
788SELECT status, count(*) AS cnt,
789 round(count(*)*100.0/sum(count(*)) OVER(),1) AS pct
790FROM payment GROUP BY status ORDER BY status;
791
792
793-- ------------------------------------ INSERT во табела REFUND ------------------------------------ --
794
795INSERT INTO REFUND (amount, reason, status, PAYMENTid)
796SELECT
797 CASE
798 WHEN random() < 0.60 THEN p.amount
799 ELSE 0
800 END AS amount,
801
802 (ARRAY[
803 'Event cancelled by organizer',
804 'Duplicate payment',
805 'Customer request',
806 'Technical error during purchase',
807 'Event rescheduled',
808 'Venue capacity issue',
809 'Medical emergency',
810 'Unable to attend'
811 ])[(random()*7)::INT + 1] AS reason,
812
813 CASE
814 WHEN random() < 0.60 THEN 'APPROVED'
815 WHEN random() < 0.85 THEN 'REQUESTED'
816 ELSE 'REJECTED'
817 END AS status,
818
819 p.id AS PAYMENTid
820
821FROM (SELECT id, amount FROM payment WHERE status = 'COMPLETED' LIMIT 50000) p;
822
823SELECT count(*) AS total_refunds FROM refund;
824SELECT status, count(*) AS cnt, round(count(*)*100.0/sum(count(*)) OVER(),1) AS pct
825FROM refund GROUP BY status ORDER BY status;
826
827-- ------------------------------------ INSERT во табела NOTIFICATION ------------------------------------ --
828INSERT INTO NOTIFICATION (message, created_at, APP_USERid)
829SELECT
830 (ARRAY[
831 'Your ticket has been confirmed.',
832 'New event available in your subscribed category.',
833 'Your order has been successfully paid.',
834 'Reminder: Your event starts tomorrow.',
835 'Your refund has been approved.',
836 'A new promo code is available for you.',
837 'Event you liked has new available seats.',
838 'Your review has been published.',
839 'Order cancellation confirmed.',
840 'New events added near your location.',
841 'Your waitlist request has been confirmed.',
842 'Payment failed. Please try again.',
843 'New event added in your city.',
844 'Your ticket has been cancelled.',
845 'Upcoming event reminder: starts in 3 days.'
846 ])[(random()*14)::INT + 1] AS message,
847
848 CURRENT_DATE - (random()*730)::INT AS created_at,
849
850 (SELECT id FROM app_user WHERE id != 1
851 ORDER BY random() LIMIT 1) AS APP_USERid
852
853FROM generate_series(1, 1000000) gs;
854
855
856-- ------------------------------------ INSERT во табела USER_EVENT ------------------------------------ --
857INSERT INTO USER_EVENT (APP_USERid, EVENTid, EVENT_ROLEid)
858SELECT DISTINCT ON (u.id, e.id)
859 u.id AS APP_USERid,
860 e.id AS EVENTid,
861 CASE
862 WHEN random() < 0.10 THEN 1 -- EVENT_ADMIN
863 WHEN random() < 0.30 THEN 2 -- SALES_MANAGER
864 WHEN random() < 0.60 THEN 3 -- INFO_ADMIN
865 ELSE 4 -- CONTENT_MANAGER
866 END AS EVENT_ROLEid
867FROM (SELECT id FROM app_user WHERE id != 1 ORDER BY random() LIMIT 5000) u
868CROSS JOIN (SELECT id FROM event ORDER BY random() LIMIT 5000) e
869WHERE random() < 0.015;
870
871SELECT count(*) AS total FROM user_event;
872SELECT er.role_name, count(*) AS cnt,
873 round(count(*)*100.0/sum(count(*)) OVER(),1) AS pct
874FROM user_event ue
875JOIN event_role er ON er.id = ue.event_roleid
876GROUP BY er.role_name
877ORDER BY er.role_name;
878
879-- ------------------------------- INSERT во табела USER_WAITLIST ------------------------------ --
880
881TRUNCATE TABLE user_waitlist;
882
883INSERT INTO USER_WAITLIST (APP_USERid, WAITLISTid)
884SELECT
885 u.id AS APP_USERid,
886 w.id AS WAITLISTid
887FROM waitlist w
888JOIN (
889 SELECT id, row_number() OVER (ORDER BY random()) AS rn
890 FROM app_user WHERE id != 1
891) u ON u.rn = (w.id % 50000) + 1;
892
893SELECT count(*) FROM user_waitlist;