DatabaseCreation: dml.sql

File dml.sql, 29.5 KB (added by 231169, 8 days ago)
Line 
1SET search_path TO myschema;
2
3-- 1. ROLES
4INSERT INTO roles (role_id, role_name, description) VALUES
5(1, 'ADMIN', 'Full system access'),
6(2, 'CUSTOMER', 'Regular buyer'),
7(3, 'SELLER', 'Store owner/vendor'),
8(4, 'SUPPORT STAFF', 'Customer service'),
9(5, 'COURIER', 'Delivery personnel');
10
11-- 2. CATEGORIES
12INSERT INTO categories (category_id, category_name, parent_category_id) VALUES
13(1, 'Computing', NULL),
14(2, 'Mobile & Tablets', NULL),
15(3, 'Audio', NULL),
16(4, 'TV & Home Theater', NULL),
17(5, 'Video Games', NULL),
18(6, 'Appliances', NULL),
19(7, 'Laptops', 1),
20(8, 'Desktops', 1),
21(9, 'PC Components', 1),
22(10, 'Smartphones', 2),
23(11, 'iPads', 2),
24(12, 'Android Tablets', 2),
25(13, 'Headphones', 3),
26(14, 'Bluetooth Speakers', 3),
27(15, 'OLED TVs', 4),
28(16, 'Projectors', 4),
29(17, 'Consoles', 5),
30(18, 'VR Headsets', 5),
31(19, 'Refrigerators', 6),
32(20, 'Washing Machines', 6);
33
34-- 3. PRODUCT_ATTRIBUTES
35INSERT INTO product_attributes (attribute_name) VALUES
36('Processor'),
37('RAM Memory'),
38('Storage (SSD/HDD)'),
39('Screen Size'),
40('Display Type'),
41('Battery Life'),
42('GPU (Graphics)'),
43('Color'),
44('Power Consumption'),
45('Energy Efficiency Rating');
46
47-- 4. MANUFACTURERS
48INSERT INTO manufacturers (manufacturer_id, name, contact_info)
49SELECT
50 i,
51 brand || ' ' || industry AS name,
52 'support@' || lower(brand) || '.com' AS contact_info
53FROM (
54 SELECT
55 i,
56 CASE
57 WHEN (i - 1) % 6 = 0 THEN 'Computing'
58 WHEN (i - 1) % 6 = 1 THEN 'Mobile'
59 WHEN (i - 1) % 6 = 2 THEN 'Sound'
60 WHEN (i - 1) % 6 = 3 THEN 'Display'
61 WHEN (i - 1) % 6 = 4 THEN 'Gaming'
62 ELSE 'Appliances'
63 END AS industry,
64 (ARRAY['Apex','Nova','Zenith','Quantum','Elite','Aura','Pixel','Sonic','Giga','Volt'])[((i / 6) % 10) + 1] AS brand
65 FROM generate_series(1, 600) AS i
66) s;
67
68-- 5. SHIPPING_METHODS
69INSERT INTO shipping_methods (method_id, method_name, cost, estimated_days) VALUES
70(1, 'Standard Delivery', 150.00, 10),
71(2, 'Express Delivery', 450.00, 3),
72(3, 'Free Shipping', 0.00, 10);
73
74-- 6. COUPONS
75INSERT INTO coupons (coupon_id, code, discount_value, discount_type, valid_from, valid_to, min_order_value) VALUES
76(1, 'EASTER24', 15.00, 'PERCENTAGE', '2024-04-15 00:00:00', '2024-04-30 23:59:59', 1500.00),
77(2, 'WOMAN8MAR', 500.00, 'FIXED', '2024-03-07 00:00:00', '2024-03-10 23:59:59', 3000.00),
78(3, 'BLACKFRIDAY24', 30.00, 'PERCENTAGE', '2024-11-25 00:00:00', '2024-11-30 23:59:59', 500.00),
79(4, 'SINGLES11', 1111.00, 'FIXED', '2024-11-11 00:00:00', '2024-11-11 23:59:59', 6000.00),
80(5, 'XMAS24', 20.00, 'PERCENTAGE', '2024-12-15 00:00:00', '2025-01-05 23:59:59', 2000.00),
81(6, 'EARTH24', 10.00, 'PERCENTAGE', '2024-04-22 00:00:00', '2024-04-22 23:59:59', 0.00),
82(7, 'WELCOME_BLINK', 200.00, 'FIXED', '2023-01-01 00:00:00', '2025-12-31 23:59:59', 1000.00),
83(8, 'LOYALTY_VIP', 25.00, 'PERCENTAGE', '2023-01-01 00:00:00', '2025-12-31 23:59:59', 5000.00);
84
85-- 7. USERS
86INSERT INTO users (user_id, email, password_hash, status, created_at)
87SELECT
88 gs,
89 CASE
90 WHEN gs = 1 THEN 'admin@blinkbuy.com'
91 WHEN gs BETWEEN 800001 AND 950000 THEN 'seller' || gs || '@blinkbuy-sellers.com'
92 WHEN gs BETWEEN 975001 AND 1000000 THEN 'courier' || gs || '@blinkbuy-logistics.com'
93 ELSE 'user' || gs || '@' || (ARRAY['gmail.com','outlook.com','yahoo.com'])[(gs % 3) + 1]
94 END AS email,
95 md5(gs::text) AS password_hash,
96 CASE WHEN gs % 1000 = 0 THEN 'INACTIVE' ELSE 'ACTIVE' END AS status,
97 '2023-01-01 00:00:00+00'::timestamptz + ((gs % 1095) * interval '1 day') AS created_at
98FROM generate_series(1, 1000000) gs;
99
100-- 8. USER_ROLES
101INSERT INTO user_roles (user_id, role_id, assigned_at)
102SELECT
103 user_id,
104 CASE
105 WHEN user_id = 1 THEN 1
106 WHEN user_id BETWEEN 2 AND 800000 THEN 2
107 WHEN user_id BETWEEN 800001 AND 950000 THEN 3
108 WHEN user_id BETWEEN 950001 AND 975000 THEN 4
109 ELSE 5
110 END AS role_id,
111 created_at::date AS assigned_at
112FROM users;
113
114-- 9. USER_PROFILES
115INSERT INTO user_profiles (user_id, first_name, last_name, phone_number, profile_picture_url)
116SELECT
117 u.user_id,
118 CASE
119 WHEN u.user_id = 1 THEN 'System'
120 WHEN ur.role_id = 3 THEN (ARRAY['ByteForge','CircuitCore','PixelWave','QuantumTech','NeonByte','TechNova','DigitalEdge','ElectroLink'])[(u.user_id % 8) + 1]
121 WHEN ur.role_id = 5 THEN (ARRAY['Fast','Rapid','Cargo','Sky','City','Speedy','Star','Blue'])[(u.user_id % 8) + 1]
122 WHEN u.user_id % 2 = 0 THEN (ARRAY['Ivan','Petar','Stefan','Igor','Goran','Darko','Bojan','Dragan'])[(u.user_id % 8) + 1]
123 ELSE (ARRAY['Marija','Elena','Ana','Jovana','Milica','Katerina','Sara','Ivana'])[(u.user_id % 8) + 1]
124 END AS first_name,
125 CASE
126 WHEN u.user_id = 1 THEN 'Administrator'
127 WHEN ur.role_id = 3 THEN (ARRAY['Technologies','Electronics','Systems','Digital','Devices','Computing','Hardware','Solutions'])[(u.user_id % 8) + 1]
128 WHEN ur.role_id = 5 THEN (ARRAY['Logistics','Delivery','Courier','Express','Post','Transport','Ship','Way'])[(u.user_id % 8) + 1]
129 WHEN u.user_id % 2 = 0 THEN (ARRAY['Stojanovski','Petrovski','Trajkov','Popov','Nikolov','Ristov','Arsov','Kuzmanov'])[(u.user_id % 8) + 1]
130 ELSE (ARRAY['Stojanovska','Petrovska','Trajkova','Popova','Nikolova','Ristovska','Arsova','Kuzmanova'])[(u.user_id % 8) + 1]
131 END AS last_name,
132 '+3897' || ((u.user_id % 6) + 1)::text || lpad((100000 + (u.user_id % 899999))::text, 6, '0') AS phone_number,
133 'https://api.dicebear.com/7.x/avataaars/svg?seed=' || u.user_id AS profile_picture_url
134FROM users u
135JOIN user_roles ur ON ur.user_id = u.user_id;
136
137-- 10. ADDRESSES
138INSERT INTO addresses (user_id, street_address, city, country, is_default, address_type)
139SELECT
140 u.user_id,
141 CASE
142 WHEN u.user_id = 1 THEN 'BlinkBuy HQ, Macedonia St. 1'
143 WHEN ur.role_id = 3 THEN 'Industrial Zone ' || (ARRAY['A','B','C'])[(u.user_id % 3) + 1] || '-' || (u.user_id % 100)
144 WHEN ur.role_id = 5 THEN 'Logistics Center Hub ' || (u.user_id % 50)
145 ELSE (ARRAY['Partizanska','Ilindenska','Jane Sandanski','Ruzveltova'])[(u.user_id % 4) + 1] || ' No.' || (u.user_id % 200)
146 END AS street_address,
147 (ARRAY['Skopje','Bitola','Kumanovo','Tetovo','Veles','Stip'])[(u.user_id % 6) + 1] AS city,
148 'Macedonia' AS country,
149 true AS is_default,
150 CASE
151 WHEN u.user_id = 1 THEN 'HEADQUARTERS'
152 WHEN ur.role_id = 3 THEN 'WAREHOUSE'
153 WHEN ur.role_id = 5 THEN 'OFFICE'
154 ELSE 'HOME'
155 END AS address_type
156FROM users u
157JOIN user_roles ur ON ur.user_id = u.user_id;
158
159-- 11. WAREHOUSES
160INSERT INTO warehouses (warehouse_name, location, user_id)
161SELECT
162 'Warehouse ' || ur.user_id || '-1' AS warehouse_name,
163 (ARRAY['Skopje Industrial Zone','Bitola Logistics Park','Kumanovo Distribution Center','Tetovo Storage Hub','Veles Warehouse Area','Stip Industrial Complex'])[(ur.user_id % 6) + 1] AS location,
164 ur.user_id
165FROM user_roles ur
166WHERE ur.role_id = 3
167UNION ALL
168SELECT
169 'Warehouse ' || ur.user_id || '-2' AS warehouse_name,
170 (ARRAY['Skopje Industrial Zone','Kumanovo Distribution Center','Tetovo Storage Hub'])[(ur.user_id % 3) + 1] AS location,
171 ur.user_id
172FROM user_roles ur
173WHERE ur.role_id = 3
174 AND ur.user_id % 2 = 0;
175
176-- 12. PRODUCTS
177INSERT INTO products (product_id, category_id, manufacturer_id, name, brand, description)
178SELECT
179 i AS product_id,
180 cat_id AS category_id,
181 manufacturer_id,
182 brand_prefix || ' ' || model_line || ' ' || (100 + (i % 900)) AS name,
183 brand_full_name AS brand,
184 'High-end device designed for professional performance and durability.' AS description
185FROM (
186 SELECT
187 i,
188 (i % 14 + 7) AS cat_id,
189 (((i % 100) * 6) + CASE
190 WHEN (i % 14 + 7) BETWEEN 7 AND 9 THEN 1
191 WHEN (i % 14 + 7) BETWEEN 10 AND 12 THEN 2
192 WHEN (i % 14 + 7) BETWEEN 13 AND 14 THEN 3
193 WHEN (i % 14 + 7) BETWEEN 15 AND 16 THEN 4
194 WHEN (i % 14 + 7) BETWEEN 17 AND 18 THEN 5
195 ELSE 6
196 END) AS manufacturer_id
197 FROM generate_series(1, 500000) i
198) x
199JOIN LATERAL (
200 SELECT name AS brand_full_name, split_part(name, ' ', 1) AS brand_prefix
201 FROM manufacturers
202 WHERE manufacturer_id = x.manufacturer_id
203) m ON true
204JOIN LATERAL (
205 SELECT category_name AS model_line
206 FROM categories
207 WHERE category_id = x.cat_id
208) c ON true;
209
210-- 13. PRODUCT_VARIANTS
211INSERT INTO product_variants (product_id, sku, price, stock_total, manufacturer_id)
212SELECT
213 p.product_id,
214 'SKU-' || p.product_id || '-' || v AS sku,
215 CASE
216 WHEN p.category_id BETWEEN 7 AND 12 THEN (15000 + (p.product_id % 80000) + v * 1000)::numeric(12,2)
217 WHEN p.category_id BETWEEN 15 AND 18 THEN (30000 + (p.product_id % 150000) + v * 1500)::numeric(12,2)
218 ELSE (5000 + (p.product_id % 40000) + v * 500)::numeric(12,2)
219 END AS price,
220 0 AS stock_total,
221 p.manufacturer_id
222FROM products p
223CROSS JOIN generate_series(1, 3) v;
224
225-- 14. PRODUCT_PRICE_HISTORY
226INSERT INTO product_price_history (variant_id, old_price, new_price, change_date)
227WITH base AS (
228 SELECT
229 pv.variant_id,
230 pv.price AS current_price,
231 CASE
232 WHEN pv.variant_id % 10 BETWEEN 0 AND 5 THEN 1
233 WHEN pv.variant_id % 10 BETWEEN 6 AND 8 THEN 2
234 ELSE 3
235 END AS history_count
236 FROM product_variants pv
237), h1 AS (
238 SELECT
239 variant_id,
240 history_count,
241 (current_price * (1 + (((variant_id % 30) + 1) / 100.0)))::numeric(12,2) AS old_price,
242 current_price AS new_price,
243 now() - (((variant_id % 6) + 1) || ' months')::interval AS change_date
244 FROM base
245), h2 AS (
246 SELECT
247 variant_id,
248 history_count,
249 (old_price * (1 + (((variant_id % 25) + 5) / 100.0)))::numeric(12,2) AS old_price,
250 old_price AS new_price,
251 change_date - ((((variant_id + 2) % 6) + 1) || ' months')::interval AS change_date
252 FROM h1
253 WHERE history_count >= 2
254), h3 AS (
255 SELECT
256 variant_id,
257 history_count,
258 (old_price * (1 + (((variant_id % 20) + 10) / 100.0)))::numeric(12,2) AS old_price,
259 old_price AS new_price,
260 change_date - ((((variant_id + 4) % 6) + 1) || ' months')::interval AS change_date
261 FROM h2
262 WHERE history_count >= 3
263)
264SELECT variant_id, old_price, new_price, change_date FROM h1
265UNION ALL
266SELECT variant_id, old_price, new_price, change_date FROM h2
267UNION ALL
268SELECT variant_id, old_price, new_price, change_date FROM h3;
269
270-- 15. INVENTORY_ITEMS
271INSERT INTO inventory_items (warehouse_id, variant_id, quantity)
272WITH sellers AS (
273 SELECT user_id, ROW_NUMBER() OVER (ORDER BY user_id) - 1 AS seller_rn
274 FROM user_roles
275 WHERE role_id = 3
276), seller_count AS (
277 SELECT COUNT(*) AS total_sellers FROM sellers
278), variant_to_seller AS (
279 SELECT pv.variant_id, s.user_id AS seller_user_id
280 FROM product_variants pv
281 CROSS JOIN seller_count sc
282 JOIN sellers s ON s.seller_rn = (pv.variant_id % sc.total_sellers)
283), seller_warehouses AS (
284 SELECT
285 warehouse_id,
286 user_id,
287 ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY warehouse_id) - 1 AS warehouse_rn,
288 COUNT(*) OVER (PARTITION BY user_id) AS warehouse_count
289 FROM warehouses
290)
291SELECT
292 sw.warehouse_id,
293 vts.variant_id,
294 (10 + (vts.variant_id % 50))::int AS quantity
295FROM variant_to_seller vts
296JOIN seller_warehouses sw
297 ON sw.user_id = vts.seller_user_id
298 AND sw.warehouse_rn = (vts.variant_id % sw.warehouse_count);
299
300UPDATE product_variants pv
301SET stock_total = s.total_quantity
302FROM (
303 SELECT variant_id, SUM(quantity)::int AS total_quantity
304 FROM inventory_items
305 GROUP BY variant_id
306) s
307WHERE s.variant_id = pv.variant_id;
308
309-- 16. PRODUCT_INSTANCES
310INSERT INTO product_instances (variant_id, warehouse_id, serial_number, status)
311SELECT
312 ii.variant_id,
313 ii.warehouse_id,
314 'SN-' || ii.inventory_id || '-' || gs || '-' || ii.variant_id AS serial_number,
315 'AVAILABLE' AS status
316FROM inventory_items ii
317JOIN product_variants pv ON pv.variant_id = ii.variant_id
318JOIN products p ON p.product_id = pv.product_id
319CROSS JOIN LATERAL generate_series(
320 1,
321 CASE
322 WHEN p.category_id IN (7,8,10,11,12,15,16,17,18,19,20) THEN LEAST(ii.quantity, 3 + ((ii.inventory_id % 4)::int))
323 WHEN p.category_id IN (9,13,14) THEN LEAST(ii.quantity, 1 + ((ii.inventory_id % 2)::int))
324 ELSE 1
325 END
326) gs;
327
328-- 17. WARRANTIES
329INSERT INTO warranties (instance_id, duration_months, terms_conditions)
330SELECT
331 pi.instance_id,
332 CASE
333 WHEN p.category_id IN (7,8,10,11,12,15,16,17,18,19,20) THEN 24
334 WHEN p.category_id IN (9,13,14) THEN 12
335 ELSE 6
336 END AS duration_months,
337 CASE
338 WHEN p.category_id IN (7,8,10,11,12,15,16,17,18,19,20) THEN 'Standard manufacturer warranty for high-value electronic devices.'
339 WHEN p.category_id IN (9,13,14) THEN 'Limited warranty for components and audio equipment.'
340 ELSE 'Basic limited warranty.'
341 END AS terms_conditions
342FROM product_instances pi
343JOIN product_variants pv ON pv.variant_id = pi.variant_id
344JOIN products p ON p.product_id = pv.product_id;
345
346-- 18. PRODUCT_ATTRIBUTE_VALUES
347INSERT INTO product_attribute_values (variant_id, attribute_id, attr_value)
348SELECT
349 pv.variant_id,
350 pa.attribute_id,
351 CASE
352 WHEN pa.attribute_name = 'Processor' AND p.category_id IN (7,8,9,10,11,12,17,18) THEN (ARRAY['Apple M3','Intel i5','Intel i7','Intel i9','Ryzen 5','Ryzen 7','Snapdragon 8 Gen 3'])[(pv.variant_id % 7) + 1]
353 WHEN pa.attribute_name = 'RAM Memory' AND p.category_id IN (7,8,10,11,12) THEN (ARRAY['8GB','16GB','32GB','64GB'])[(pv.variant_id % 4) + 1]
354 WHEN pa.attribute_name = 'Storage (SSD/HDD)' AND p.category_id IN (7,8,9,10,11,12,17,18) THEN (ARRAY['128GB','256GB','512GB','1TB','2TB'])[(pv.variant_id % 5) + 1]
355 WHEN pa.attribute_name = 'Screen Size' AND p.category_id IN (7,10,11,12,15,16,18) THEN (ARRAY['6.1"','10.9"','14"','15.6"','55"','65"','75"'])[(pv.variant_id % 7) + 1]
356 WHEN pa.attribute_name = 'Display Type' AND p.category_id IN (7,10,11,12,15,16,18) THEN (ARRAY['LCD','LED','OLED','QLED','Mini-LED'])[(pv.variant_id % 5) + 1]
357 WHEN pa.attribute_name = 'Battery Life' AND p.category_id IN (7,10,11,12,13,14,18) THEN (ARRAY['6 hours','8 hours','10 hours','12 hours','24 hours'])[(pv.variant_id % 5) + 1]
358 WHEN pa.attribute_name = 'GPU (Graphics)' AND p.category_id IN (7,8,9,17,18) THEN (ARRAY['Integrated','RTX 4060','RTX 4070','RTX 4080','Radeon RX 7800'])[(pv.variant_id % 5) + 1]
359 WHEN pa.attribute_name = 'Color' THEN (ARRAY['Black','White','Silver','Blue','Gray'])[(pv.variant_id % 5) + 1]
360 ELSE 'Not specified'
361 END AS attr_value
362FROM product_variants pv
363JOIN products p ON p.product_id = pv.product_id
364CROSS JOIN product_attributes pa;
365
366-- 19. REVIEWS
367INSERT INTO reviews (user_id, product_id, rating, comment_text, created_at)
368SELECT
369 ((gs * 3571) % 799999 + 2)::bigint AS user_id,
370 ((gs * 7919) % 500000 + 1)::bigint AS product_id,
371 CASE
372 WHEN gs % 100 < 50 THEN 5
373 WHEN gs % 100 < 70 THEN 4
374 WHEN gs % 100 < 85 THEN 3
375 WHEN gs % 100 < 95 THEN 2
376 ELSE 1
377 END AS rating,
378 CASE
379 WHEN gs % 100 < 50 THEN 'Excellent product, works perfectly and feels premium.'
380 WHEN gs % 100 < 70 THEN 'Very good product, satisfied with the purchase.'
381 WHEN gs % 100 < 85 THEN 'Average product, works fine but nothing special.'
382 WHEN gs % 100 < 95 THEN 'Not fully satisfied, expected better quality.'
383 ELSE 'Poor experience, product did not meet expectations.'
384 END AS comment_text,
385 now() - ((gs % 365) * interval '1 day') AS created_at
386FROM generate_series(1, 300000) gs;
387
388-- 20. REVIEW_HELPFULNESS
389INSERT INTO review_helpfulness (user_id, review_id, vote_type, voted_at)
390SELECT DISTINCT ON ((((gs::bigint * 3571) % 799999) + 2), (((gs::bigint * 7919) % 300000) + 1))
391 (((gs::bigint * 3571) % 799999) + 2)::bigint AS user_id,
392 (((gs::bigint * 7919) % 300000) + 1)::bigint AS review_id,
393 CASE WHEN gs % 3 IN (0,1) THEN 'HELPFUL' ELSE 'NOT_HELPFUL' END AS vote_type,
394 now() - ((gs % 90) * interval '1 day') AS voted_at
395FROM generate_series(1, 500000) gs;
396
397-- 21. LOYALTY_ACCOUNTS
398INSERT INTO loyalty_accounts (user_id, current_balance, last_updated)
399SELECT
400 user_id,
401 0 AS current_balance,
402 now() AS last_updated
403FROM user_roles
404WHERE role_id = 2;
405
406-- 22. WISHLISTS
407INSERT INTO wishlists (user_id, created_at)
408SELECT
409 user_id,
410 '2023-01-01 00:00:00+00'::timestamptz + ((user_id % 700) * interval '1 day') AS created_at
411FROM user_roles
412WHERE role_id = 2;
413
414-- 23. WISHLIST_ITEMS
415INSERT INTO wishlist_items (wishlist_id, variant_id, added_at)
416SELECT
417 w.wishlist_id,
418 ((w.user_id * 7919 + gs * 3571)::bigint % 1500000 + 1)::bigint AS variant_id,
419 w.created_at + (gs * interval '1 day') AS added_at
420FROM wishlists w
421CROSS JOIN LATERAL generate_series(1, CASE WHEN w.user_id % 100 < 70 THEN 1 ELSE 2 END) gs
422ON CONFLICT (wishlist_id, variant_id) DO NOTHING;
423
424-- 24. PRODUCT_WAITLISTS
425INSERT INTO product_waitlists (user_id, variant_id, added_at, status)
426SELECT DISTINCT ON (user_id, variant_id)
427 ((gs * 3571) % 799999 + 2)::bigint AS user_id,
428 ((gs * 7919) % 1500000 + 1)::bigint AS variant_id,
429 now() - ((gs % 120) * interval '1 day') AS added_at,
430 CASE
431 WHEN gs % 100 < 70 THEN 'ACTIVE'
432 WHEN gs % 100 < 85 THEN 'NOTIFIED'
433 WHEN gs % 100 < 95 THEN 'REMOVED'
434 ELSE 'FULFILLED'
435 END AS status
436FROM generate_series(1, 120000) gs;
437
438-- 25. ORDERS
439INSERT INTO orders (order_id, user_id, shipping_method_id, order_date, total_amount, status)
440SELECT
441 gs AS order_id,
442 ((gs * 3571) % 799999 + 2)::bigint AS user_id,
443 CASE WHEN gs % 100 < 15 THEN NULL ELSE ((gs % 3) + 1)::bigint END AS shipping_method_id,
444 CASE WHEN gs % 100 < 15 THEN NULL ELSE '2024-01-01 00:00:00+00'::timestamptz + ((gs % 365) * interval '1 day') END AS order_date,
445 CASE WHEN gs % 100 < 15 THEN NULL ELSE 1::numeric(12,2) END AS total_amount,
446 CASE
447 WHEN gs % 100 < 15 THEN 'CART'
448 WHEN gs % 100 < 35 THEN 'PLACED'
449 WHEN gs % 100 < 55 THEN 'PAID'
450 WHEN gs % 100 < 75 THEN 'SHIPPED'
451 WHEN gs % 100 < 95 THEN 'COMPLETED'
452 ELSE 'CANCELLED'
453 END AS status
454FROM generate_series(1, 2000000) gs;
455
456-- 26. ORDER_ITEMS
457INSERT INTO order_items (order_id, price_history_id, variant_id, quantity, unit_price)
458WITH latest_price AS (
459 SELECT DISTINCT ON (variant_id)
460 history_id,
461 variant_id,
462 new_price
463 FROM product_price_history
464 ORDER BY variant_id, change_date DESC, history_id DESC
465)
466SELECT
467 o.order_id,
468 lp.history_id AS price_history_id,
469 ov.variant_id,
470 CASE
471 WHEN p.category_id IN (7,8,10,11,12,15,16,17,18,19,20) THEN ((o.order_id + gs.i) % 3) + 1
472 ELSE 1
473 END AS quantity,
474 lp.new_price AS unit_price
475FROM orders o
476CROSS JOIN LATERAL generate_series(1, 5) gs(i)
477CROSS JOIN LATERAL (
478 SELECT ((o.order_id * 7919 + gs.i * 3571)::bigint % 1500000 + 1)::bigint AS variant_id
479) ov
480JOIN latest_price lp ON lp.variant_id = ov.variant_id
481JOIN product_variants pv ON pv.variant_id = ov.variant_id
482JOIN products p ON p.product_id = pv.product_id;
483
484UPDATE orders o
485SET total_amount = s.order_total
486FROM (
487 SELECT order_id, SUM(quantity * unit_price)::numeric(12,2) AS order_total
488 FROM order_items
489 GROUP BY order_id
490) s
491WHERE s.order_id = o.order_id
492 AND o.status <> 'CART';
493
494WITH limits AS (
495 SELECT
496 percentile_cont(0.50) WITHIN GROUP (ORDER BY total_amount) AS p50_limit,
497 percentile_cont(0.75) WITHIN GROUP (ORDER BY total_amount) AS p75_limit
498 FROM orders
499 WHERE status <> 'CART'
500 AND total_amount IS NOT NULL
501)
502UPDATE orders o
503SET shipping_method_id = CASE
504 WHEN o.status = 'CART' THEN NULL
505 WHEN o.total_amount < limits.p50_limit THEN 1
506 WHEN o.total_amount < limits.p75_limit THEN 2
507 ELSE 3
508END
509FROM limits;
510
511-- 27. ORDER_STATUS_HISTORY
512INSERT INTO order_status_history (order_id, old_status, new_status, change_date)
513SELECT
514 o.order_id,
515 h.old_status,
516 h.new_status,
517 o.order_date + h.time_offset AS change_date
518FROM orders o
519CROSS JOIN LATERAL (
520 SELECT 'CART' AS old_status, 'PLACED' AS new_status, (((o.order_id % 10) + 5) * interval '1 minute') AS time_offset
521 WHERE o.status IN ('PLACED','PAID','SHIPPED','COMPLETED','CANCELLED')
522 UNION ALL
523 SELECT 'PLACED', 'PAID', (((o.order_id % 60) + 20) * interval '1 minute')
524 WHERE o.status IN ('PAID','SHIPPED','COMPLETED')
525 UNION ALL
526 SELECT 'PAID', 'SHIPPED', (((o.order_id % 3) + 1) * interval '1 day')
527 WHERE o.status IN ('SHIPPED','COMPLETED')
528 UNION ALL
529 SELECT 'SHIPPED', 'COMPLETED', (((o.order_id % 7) + 4) * interval '1 day')
530 WHERE o.status = 'COMPLETED'
531 UNION ALL
532 SELECT 'PLACED', 'CANCELLED', (((o.order_id % 24) + 1) * interval '1 hour')
533 WHERE o.status = 'CANCELLED'
534) h
535WHERE o.status <> 'CART';
536
537-- 28. ORDER_DISCOUNTS
538INSERT INTO order_discounts (order_id, coupon_id, applied_at, amount_saved)
539WITH valid_orders AS (
540 SELECT order_id, order_date, total_amount
541 FROM orders
542 WHERE status <> 'CART'
543 AND total_amount IS NOT NULL
544 AND order_id % 5 = 0
545), eligible_coupons AS (
546 SELECT
547 vo.order_id,
548 vo.order_date,
549 vo.total_amount,
550 c.coupon_id,
551 c.discount_type,
552 c.discount_value,
553 ROW_NUMBER() OVER (PARTITION BY vo.order_id ORDER BY c.coupon_id) AS rn,
554 COUNT(*) OVER (PARTITION BY vo.order_id) AS cnt
555 FROM valid_orders vo
556 JOIN coupons c
557 ON vo.total_amount >= COALESCE(c.min_order_value, 0)
558 AND vo.order_date BETWEEN c.valid_from AND c.valid_to
559)
560SELECT
561 order_id,
562 coupon_id,
563 order_date + interval '10 minutes' AS applied_at,
564 LEAST(total_amount, CASE WHEN upper(discount_type) LIKE '%PERCENT%' THEN total_amount * discount_value / 100.0 ELSE discount_value END)::numeric(12,2) AS amount_saved
565FROM eligible_coupons
566WHERE rn = ((order_id * 7919)::bigint % cnt) + 1
567ON CONFLICT (order_id, coupon_id) DO NOTHING;
568
569-- 29. PAYMENTS
570INSERT INTO payments (order_id, payment_method, amount, payment_status, transaction_id, payment_date)
571SELECT
572 o.order_id,
573 (ARRAY['CARD','PAYPAL','BANK_TRANSFER','CASH_ON_DELIVERY'])[(o.order_id % 4) + 1] AS payment_method,
574 GREATEST(o.total_amount - COALESCE(od.discount_total, 0), 0)::numeric(12,2) AS amount,
575 CASE
576 WHEN o.status IN ('PAID','SHIPPED','COMPLETED') THEN 'SUCCESS'
577 WHEN o.status = 'PLACED' THEN 'PENDING'
578 WHEN o.status = 'CANCELLED' THEN CASE WHEN o.order_id % 2 = 0 THEN 'FAILED' ELSE 'REFUNDED' END
579 ELSE 'FAILED'
580 END AS payment_status,
581 'TXN-' || o.order_id || '-MAIN' AS transaction_id,
582 o.order_date + interval '30 minutes' AS payment_date
583FROM orders o
584LEFT JOIN (
585 SELECT order_id, SUM(amount_saved) AS discount_total
586 FROM order_discounts
587 GROUP BY order_id
588) od ON od.order_id = o.order_id
589WHERE o.status <> 'CART';
590
591-- 30. LOYALTY_HISTORY
592INSERT INTO loyalty_history (loyalty_account_id, order_id, payment_id, points_change, transaction_type, description, created_at)
593SELECT
594 la.loyalty_account_id,
595 o.order_id,
596 p.payment_id,
597 CASE
598 WHEN p.payment_status = 'SUCCESS' THEN floor(p.amount / 100)::int
599 WHEN p.payment_status = 'REFUNDED' THEN -floor(p.amount / 100)::int
600 ELSE 0
601 END AS points_change,
602 CASE
603 WHEN p.payment_status = 'SUCCESS' THEN 'EARN'
604 WHEN p.payment_status = 'REFUNDED' THEN 'REFUND'
605 ELSE 'ADJUSTMENT'
606 END AS transaction_type,
607 CASE
608 WHEN p.payment_status = 'SUCCESS' THEN 'Points earned from successful payment.'
609 WHEN p.payment_status = 'REFUNDED' THEN 'Points reversed because payment was refunded.'
610 ELSE 'No point movement for unsuccessful payment.'
611 END AS description,
612 p.payment_date AS created_at
613FROM payments p
614JOIN orders o ON o.order_id = p.order_id
615JOIN loyalty_accounts la ON la.user_id = o.user_id
616WHERE p.payment_status IN ('SUCCESS','REFUNDED');
617
618UPDATE loyalty_accounts la
619SET current_balance = GREATEST(s.balance, 0),
620 last_updated = now()
621FROM (
622 SELECT loyalty_account_id, SUM(points_change)::int AS balance
623 FROM loyalty_history
624 GROUP BY loyalty_account_id
625) s
626WHERE s.loyalty_account_id = la.loyalty_account_id;
627
628-- 31. SHIPMENTS
629INSERT INTO shipments (order_id, address_id, courier_id, tracking_number, shipped_date, estimated_arrival, delivered_date, status)
630SELECT
631 o.order_id,
632 a.address_id,
633 975001 + (o.order_id % 25000) AS courier_id,
634 'TRK-' || o.order_id AS tracking_number,
635 CASE WHEN o.status IN ('SHIPPED','COMPLETED') THEN o.order_date + (((o.order_id % 3) + 1) * interval '1 day') ELSE NULL END AS shipped_date,
636 CASE WHEN o.status IN ('SHIPPED','COMPLETED') THEN (o.order_date + (((o.order_id % 10) + 3) * interval '1 day'))::date ELSE NULL END AS estimated_arrival,
637 CASE WHEN o.status = 'COMPLETED' THEN o.order_date + (((o.order_id % 7) + 4) * interval '1 day') ELSE NULL END AS delivered_date,
638 CASE
639 WHEN o.status = 'COMPLETED' THEN 'DELIVERED'
640 WHEN o.status = 'SHIPPED' THEN CASE WHEN o.order_id % 2 = 0 THEN 'SHIPPED' ELSE 'IN_TRANSIT' END
641 ELSE 'PENDING'
642 END AS status
643FROM orders o
644JOIN addresses a ON a.user_id = o.user_id AND a.is_default = true
645WHERE o.status IN ('PAID','SHIPPED','COMPLETED');
646
647-- 32. SHIPMENT_ITEMS
648INSERT INTO shipment_items (shipment_id, order_item_id, instance_id, quantity_shipped)
649WITH demand AS (
650 SELECT
651 s.shipment_id,
652 oi.order_item_id,
653 oi.variant_id,
654 ROW_NUMBER() OVER (PARTITION BY oi.variant_id ORDER BY s.shipment_id, oi.order_item_id, gs) AS rn
655 FROM shipments s
656 JOIN orders o ON o.order_id = s.order_id
657 JOIN order_items oi ON oi.order_id = o.order_id
658 CROSS JOIN LATERAL generate_series(1, oi.quantity) gs
659 WHERE o.status IN ('SHIPPED','COMPLETED')
660), available_instances AS (
661 SELECT
662 pi.instance_id,
663 pi.variant_id,
664 ROW_NUMBER() OVER (PARTITION BY pi.variant_id ORDER BY pi.instance_id) AS rn
665 FROM product_instances pi
666 WHERE pi.status = 'AVAILABLE'
667)
668SELECT
669 d.shipment_id,
670 d.order_item_id,
671 ai.instance_id,
672 1 AS quantity_shipped
673FROM demand d
674JOIN available_instances ai
675 ON ai.variant_id = d.variant_id
676 AND ai.rn = d.rn;
677
678UPDATE product_instances pi
679SET status = 'DELIVERED'
680FROM shipment_items si
681WHERE si.instance_id = pi.instance_id;
682
683UPDATE inventory_items ii
684SET quantity = s.available_count
685FROM (
686 SELECT variant_id, warehouse_id, COUNT(*)::int AS available_count
687 FROM product_instances
688 WHERE status = 'AVAILABLE'
689 GROUP BY variant_id, warehouse_id
690) s
691WHERE s.variant_id = ii.variant_id
692 AND s.warehouse_id = ii.warehouse_id;
693
694UPDATE inventory_items ii
695SET quantity = 0
696WHERE NOT EXISTS (
697 SELECT 1
698 FROM product_instances pi
699 WHERE pi.variant_id = ii.variant_id
700 AND pi.warehouse_id = ii.warehouse_id
701 AND pi.status = 'AVAILABLE'
702);
703
704UPDATE product_variants pv
705SET stock_total = COALESCE(s.total_quantity, 0)
706FROM (
707 SELECT variant_id, SUM(quantity)::int AS total_quantity
708 FROM inventory_items
709 GROUP BY variant_id
710) s
711WHERE s.variant_id = pv.variant_id;
712
713-- 33. AUTH_LOGS
714INSERT INTO auth_logs (user_id, login_timestamp, ip_address, device_info, status)
715SELECT
716 ((gs * 3571) % 1000000 + 1)::bigint AS user_id,
717 now() - ((gs % 365) * interval '1 day'),
718 '192.168.' || (gs % 255) || '.' || ((gs * 7) % 255) AS ip_address,
719 (ARRAY['iPhone 15 Pro','Windows 11 / Chrome','MacOS / Safari','Android 14 / Firefox'])[(gs % 4) + 1] AS device_info,
720 CASE WHEN gs % 100 < 85 THEN 'SUCCESS' ELSE 'FAILED' END AS status
721FROM generate_series(1, 1000000) gs;
722
723-- 34. USER_SESSIONS
724INSERT INTO user_sessions (user_id, session_token, login_time, expiry_time)
725SELECT
726 user_id,
727 md5(user_id::text || '-session-token') AS session_token,
728 now() - interval '1 hour' AS login_time,
729 now() + interval '2 hours' AS expiry_time
730FROM users
731WHERE user_id BETWEEN 1 AND 1000000;
732
733-- 35. USER_NOTIFICATIONS
734INSERT INTO user_notifications (user_id, type, message, sent_at)
735SELECT
736 ur.user_id,
737 CASE gs.t
738 WHEN 1 THEN 'ORDER_UPDATE'
739 WHEN 2 THEN 'PRICE_DROP'
740 WHEN 3 THEN 'PROMOTION'
741 WHEN 4 THEN 'ACCOUNT_SECURITY'
742 WHEN 5 THEN 'SHIPMENT_UPDATE'
743 WHEN 6 THEN 'REVIEW_REQUEST'
744 ELSE 'WISHLIST_UPDATE'
745 END AS type,
746 CASE gs.t
747 WHEN 1 THEN 'Your order has been updated and is now being processed.'
748 WHEN 2 THEN 'Good news! An item in your cart has a new lower price.'
749 WHEN 3 THEN 'Flash Sale! Use code BLINK20 for 20% off your next tech purchase.'
750 WHEN 4 THEN 'Security alert: A new login was detected on your account.'
751 WHEN 5 THEN 'Your BlinkBuy package is out for delivery with our courier.'
752 WHEN 6 THEN 'How do you like your new device? Share your thoughts with a review.'
753 ELSE 'An item from your wishlist is back in stock.'
754 END AS message,
755 now() - ((ur.user_id % 60) * interval '1 day') AS sent_at
756FROM user_roles ur
757CROSS JOIN LATERAL (SELECT ((ur.user_id % 7) + 1) AS t) gs
758WHERE ur.role_id = 2;
759
760-- 36. SUPPORT_TICKETS
761INSERT INTO support_tickets (user_id, subject, message_body, status, priority, created_at, resolved_at)
762SELECT
763 ((gs * 3571) % 799999 + 2)::bigint AS user_id,
764 'Support request #' || gs AS subject,
765 'Customer reported an issue with an order, product, payment, shipment, or account setting.' AS message_body,
766 CASE
767 WHEN gs % 100 < 35 THEN 'OPEN'
768 WHEN gs % 100 < 60 THEN 'IN_PROGRESS'
769 WHEN gs % 100 < 85 THEN 'RESOLVED'
770 ELSE 'CLOSED'
771 END AS status,
772 CASE
773 WHEN gs % 100 < 70 THEN 'LOW'
774 WHEN gs % 100 < 90 THEN 'MEDIUM'
775 ELSE 'HIGH'
776 END AS priority,
777 now() - ((gs % 180) * interval '1 day') AS created_at,
778 CASE WHEN gs % 100 >= 60 THEN now() - ((gs % 100) * interval '1 day') ELSE NULL END AS resolved_at
779FROM generate_series(1, 40000) gs;