| 1 | -- ============================================================
|
|---|
| 2 | -- View 1: daily_clinic_schedule
|
|---|
| 3 | --
|
|---|
| 4 | -- Primary filter: date_appointment and employee_id
|
|---|
| 5 | -- ============================================================
|
|---|
| 6 |
|
|---|
| 7 | CREATE OR REPLACE VIEW daily_clinic_schedule AS
|
|---|
| 8 | SELECT
|
|---|
| 9 | a.id AS appointment_id,
|
|---|
| 10 | a.date_appointment,
|
|---|
| 11 | a.reason,
|
|---|
| 12 | o.id AS owner_id,
|
|---|
| 13 | o.first_name || ' ' || o.last_name AS owner_name,
|
|---|
| 14 | o.phone AS owner_phone,
|
|---|
| 15 | p.id AS pet_id,
|
|---|
| 16 | p.name AS pet_name,
|
|---|
| 17 | p.type AS pet_type,
|
|---|
| 18 | e.id AS examination_id,
|
|---|
| 19 | e.status AS examination_status,
|
|---|
| 20 | emp.id AS employee_id,
|
|---|
| 21 | emp.first_name || ' ' || emp.last_name AS employee_name,
|
|---|
| 22 | rl.name AS employee_role,
|
|---|
| 23 | er.id AS room_id,
|
|---|
| 24 | er.room_number,
|
|---|
| 25 | er.type AS room_type
|
|---|
| 26 | FROM appointment a
|
|---|
| 27 | JOIN owner o ON o.id = a.owner_id
|
|---|
| 28 | JOIN pet p ON p.id = a.pet_id
|
|---|
| 29 | LEFT JOIN examination e ON e.appointment_id = a.id
|
|---|
| 30 | LEFT JOIN employee emp ON emp.id = e.employee_id
|
|---|
| 31 | LEFT JOIN role rl ON rl.id = emp.role_id
|
|---|
| 32 | LEFT JOIN examination_room er ON er.id = e.examination_room_id;
|
|---|
| 33 |
|
|---|
| 34 | SELECT * FROM daily_clinic_schedule WHERE date_appointment = '2025-07-07';
|
|---|
| 35 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM daily_clinic_schedule WHERE date_appointment = '2025-07-07';
|
|---|
| 36 |
|
|---|
| 37 | SELECT * FROM daily_clinic_schedule
|
|---|
| 38 | WHERE employee_id = 3 AND date_appointment = '2025-07-07';
|
|---|
| 39 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM daily_clinic_schedule
|
|---|
| 40 | WHERE employee_id = 3 AND date_appointment = '2025-07-07';
|
|---|
| 41 |
|
|---|
| 42 | -- INSERT into appointment
|
|---|
| 43 | INSERT INTO appointment (date_appointment, reason, phone, owner_id, pet_id)
|
|---|
| 44 | VALUES ('2025-07-07', 'Routine checkup', '+389 71 271 919', 1, 385);
|
|---|
| 45 | -- UPDATE on appointment
|
|---|
| 46 | UPDATE appointment
|
|---|
| 47 | SET reason = 'Follow-up visit'
|
|---|
| 48 | WHERE date_appointment = '2025-07-07' AND owner_id = 1;
|
|---|
| 49 |
|
|---|
| 50 | -- INSERT into examination
|
|---|
| 51 | INSERT INTO examination (date_examination, status, appointment_id, employee_id, examination_room_id)
|
|---|
| 52 | VALUES ('2025-07-10', 'scheduled', 850801, 3, 5);
|
|---|
| 53 | -- UPDATE on examination
|
|---|
| 54 | UPDATE examination
|
|---|
| 55 | SET status = 'completed'
|
|---|
| 56 | WHERE employee_id = 3 AND date_examination = '2025-07-10';
|
|---|
| 57 |
|
|---|
| 58 | -- INDEXES
|
|---|
| 59 | -- CREATE INDEX idx_examination_employee on examination (employee_id);
|
|---|
| 60 | DROP INDEX IF EXISTS idx_examination_employee;
|
|---|
| 61 | CREATE INDEX idx_appointment_date on appointment (date_appointment);
|
|---|
| 62 | CREATE INDEX idx_examination_appointment ON examination (appointment_id);
|
|---|
| 63 |
|
|---|
| 64 | -- INSERT into appointment
|
|---|
| 65 | INSERT INTO appointment (date_appointment, reason, phone, owner_id, pet_id)
|
|---|
| 66 | VALUES ('2025-07-08', 'Vaccination check', '+389 77 979 331', 2, 230);
|
|---|
| 67 | -- UPDATE on appointment
|
|---|
| 68 | UPDATE appointment
|
|---|
| 69 | SET reason = 'Vaccination follow-up visit'
|
|---|
| 70 | WHERE date_appointment = '2025-07-08' AND owner_id = 2;
|
|---|
| 71 |
|
|---|
| 72 | -- INSERT into examination
|
|---|
| 73 | INSERT INTO examination (date_examination, status, appointment_id, employee_id, examination_room_id)
|
|---|
| 74 | VALUES ('2025-07-15', 'scheduled', 850802, 3, 5);
|
|---|
| 75 | -- UPDATE on examination
|
|---|
| 76 | UPDATE examination
|
|---|
| 77 | SET status = 'completed'
|
|---|
| 78 | WHERE employee_id = 3 AND date_examination = '2025-07-15';
|
|---|
| 79 |
|
|---|
| 80 |
|
|---|
| 81 | -- ============================================================
|
|---|
| 82 | -- View 2: pet_medical_history
|
|---|
| 83 | --
|
|---|
| 84 | -- Primary filter: pet_id (also usable by owner_id, date_examination)
|
|---|
| 85 | -- Use case: vet or assistant pulls up a pet's full medical timeline
|
|---|
| 86 | -- during a visit: appointments, examinations, and every treatment
|
|---|
| 87 | -- (consultation/vaccination/prescription/operation) with its
|
|---|
| 88 | -- type-specific attributes collapsed into one JSON blob, since
|
|---|
| 89 | -- each treatment_type has a different attribute set (EAV pattern).
|
|---|
| 90 | -- ============================================================
|
|---|
| 91 |
|
|---|
| 92 | CREATE OR REPLACE VIEW pet_medical_history AS
|
|---|
| 93 | SELECT
|
|---|
| 94 | p.id AS pet_id,
|
|---|
| 95 | p.name AS pet_name,
|
|---|
| 96 | p.type AS pet_type,
|
|---|
| 97 | p.breed,
|
|---|
| 98 | p.age,
|
|---|
| 99 | o.id AS owner_id,
|
|---|
| 100 | o.first_name || ' ' || o.last_name AS owner_name,
|
|---|
| 101 | o.phone AS owner_phone,
|
|---|
| 102 | a.id AS appointment_id,
|
|---|
| 103 | a.date_appointment,
|
|---|
| 104 | a.reason AS appointment_reason,
|
|---|
| 105 | e.id AS examination_id,
|
|---|
| 106 | e.date_examination,
|
|---|
| 107 | e.status AS examination_status,
|
|---|
| 108 | e.description AS examination_notes,
|
|---|
| 109 | emp.id AS employee_id,
|
|---|
| 110 | emp.first_name || ' ' || emp.last_name AS attending_employee,
|
|---|
| 111 | r.name AS employee_role,
|
|---|
| 112 | t.id AS treatment_id,
|
|---|
| 113 | t.date_treatment,
|
|---|
| 114 | tt.name AS treatment_type,
|
|---|
| 115 | t.notes AS treatment_notes,
|
|---|
| 116 | (
|
|---|
| 117 | SELECT json_object_agg(ta.name, tav.value)
|
|---|
| 118 | FROM treatment_attribute_value tav
|
|---|
| 119 | JOIN treatment_attribute ta ON ta.id = tav.treatment_attribute_id
|
|---|
| 120 | WHERE tav.treatment_id = t.id
|
|---|
| 121 | ) AS treatment_details
|
|---|
| 122 | FROM pet p
|
|---|
| 123 | JOIN owner o ON o.id = p.owner_id
|
|---|
| 124 | LEFT JOIN appointment a ON a.pet_id = p.id
|
|---|
| 125 | LEFT JOIN examination e ON e.appointment_id = a.id
|
|---|
| 126 | LEFT JOIN employee emp ON emp.id = e.employee_id
|
|---|
| 127 | LEFT JOIN role r ON r.id = emp.role_id
|
|---|
| 128 | LEFT JOIN treatment t ON t.examination_id = e.id
|
|---|
| 129 | LEFT JOIN treatment_type tt ON tt.id = t.treatment_type_id;
|
|---|
| 130 |
|
|---|
| 131 | SELECT * FROM pet_medical_history WHERE pet_id = 9956;
|
|---|
| 132 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM pet_medical_history WHERE pet_id = 9956;
|
|---|
| 133 |
|
|---|
| 134 | SELECT id, treatment_type_id, examination_id FROM treatment LIMIT 5;
|
|---|
| 135 |
|
|---|
| 136 | -- INSERT into treatment, treatment_attribute_value
|
|---|
| 137 | INSERT INTO treatment (examination_id, treatment_type_id, date_treatment, notes)
|
|---|
| 138 | VALUES (1726, 2, CURRENT_DATE, 'Follow-up dosage adjustment');
|
|---|
| 139 | -- SELECT max(id) FROM treatment
|
|---|
| 140 |
|
|---|
| 141 | INSERT INTO treatment_attribute_value (treatment_id, treatment_attribute_id, value)
|
|---|
| 142 | VALUES (577416, 13, 'false');
|
|---|
| 143 |
|
|---|
| 144 | -- UPDATE treatment, treatment_attribute_value
|
|---|
| 145 |
|
|---|
| 146 | -- SELECT tav.treatment_id, tav.value
|
|---|
| 147 | -- FROM treatment_attribute_value tav
|
|---|
| 148 | -- JOIN treatment t ON t.id = tav.treatment_id
|
|---|
| 149 | -- WHERE t.treatment_type_id = 4
|
|---|
| 150 | -- AND tav.treatment_attribute_id = 23
|
|---|
| 151 | -- LIMIT 5;
|
|---|
| 152 |
|
|---|
| 153 | UPDATE treatment
|
|---|
| 154 | SET notes = 'Updated post-op notes'
|
|---|
| 155 | WHERE id = 1577;
|
|---|
| 156 |
|
|---|
| 157 | UPDATE treatment_attribute_value
|
|---|
| 158 | SET value = '122'
|
|---|
| 159 | WHERE treatment_id = 1577 AND treatment_attribute_id = 23;
|
|---|
| 160 |
|
|---|
| 161 | CREATE INDEX idx_appointment_pet ON appointment (pet_id);
|
|---|
| 162 | -- CREATE INDEX idx_treatment_attribute_value_treatment ON treatment_attribute_value (treatment_id);
|
|---|
| 163 | DROP INDEX IF EXISTS idx_treatment_attribute_value_treatment;
|
|---|
| 164 |
|
|---|
| 165 | -- INSERT into treatment, treatment_attribute_value
|
|---|
| 166 | INSERT INTO treatment (examination_id, treatment_type_id, date_treatment, notes)
|
|---|
| 167 | VALUES (1726, 2, CURRENT_DATE, 'Second follow-up dosage adjustment');
|
|---|
| 168 | -- SELECT max(id) FROM treatment;
|
|---|
| 169 |
|
|---|
| 170 | INSERT INTO treatment_attribute_value (treatment_id, treatment_attribute_id, value)
|
|---|
| 171 | VALUES (577417, 13, 'false');
|
|---|
| 172 |
|
|---|
| 173 | -- UPDATE treatment, treatment_attribute_value
|
|---|
| 174 | UPDATE treatment
|
|---|
| 175 | SET notes = 'Updated dosage per second follow-up'
|
|---|
| 176 | WHERE id = 1570;
|
|---|
| 177 |
|
|---|
| 178 | UPDATE treatment_attribute_value
|
|---|
| 179 | SET value = 'true'
|
|---|
| 180 | WHERE treatment_id = 1571 AND treatment_attribute_id = 13;
|
|---|
| 181 |
|
|---|
| 182 |
|
|---|
| 183 | -- ============================================================
|
|---|
| 184 | -- View 3: active_prescriptions_for_pet
|
|---|
| 185 | --
|
|---|
| 186 | -- Primary filter: pet_id (also usable by medicine_id)
|
|---|
| 187 | -- Use case: pet_id - vet checks what a pet is currently prescribed
|
|---|
| 188 | -- before adding a new treatment, to catch interactions or repeat
|
|---|
| 189 | -- prescriptions. medicine_id - clinic checks which currently
|
|---|
| 190 | -- active patients are on a given medicine, during a
|
|---|
| 191 | -- medication recall or an interaction check. Filters to
|
|---|
| 192 | -- prescriptions where today falls within date_start/date_end.
|
|---|
| 193 | -- ============================================================
|
|---|
| 194 |
|
|---|
| 195 | CREATE OR REPLACE VIEW active_prescriptions_for_pet AS
|
|---|
| 196 | SELECT
|
|---|
| 197 | p.id AS pet_id,
|
|---|
| 198 | p.name AS pet_name,
|
|---|
| 199 | o.id AS owner_id,
|
|---|
| 200 | o.first_name || ' ' || o.last_name AS owner_name,
|
|---|
| 201 | pr.id AS prescription_id,
|
|---|
| 202 | pr.date_start,
|
|---|
| 203 | pr.date_end,
|
|---|
| 204 | pr.description AS prescription_notes,
|
|---|
| 205 | m.id AS medicine_id,
|
|---|
| 206 | m.name AS medicine_name,
|
|---|
| 207 | pm.dosage,
|
|---|
| 208 | pm.num_days
|
|---|
| 209 | FROM pet p
|
|---|
| 210 | JOIN appointment a ON a.pet_id = p.id
|
|---|
| 211 | JOIN owner o ON o.id = p.owner_id
|
|---|
| 212 | JOIN examination e ON e.appointment_id = a.id
|
|---|
| 213 | JOIN prescription pr ON pr.examination_id = e.id
|
|---|
| 214 | JOIN prescription_medicine pm ON pm.prescription_id = pr.id
|
|---|
| 215 | JOIN medicine m ON m.id = pm.medicine_id
|
|---|
| 216 | WHERE pr.date_start <= CURRENT_DATE AND pr.date_end >= CURRENT_DATE;
|
|---|
| 217 |
|
|---|
| 218 | -- 1. By pet (idx_appointment_pet + PK on prescription_medicine)
|
|---|
| 219 | SELECT * FROM active_prescriptions_for_pet WHERE pet_id = 3;
|
|---|
| 220 | EXPLAIN (ANALYZE, BUFFERS)
|
|---|
| 221 | SELECT * FROM active_prescriptions_for_pet WHERE pet_id = 3;
|
|---|
| 222 |
|
|---|
| 223 | -- 2. By medicine (seq scan)
|
|---|
| 224 | SELECT * FROM active_prescriptions_for_pet WHERE medicine_id = 47;
|
|---|
| 225 | EXPLAIN (ANALYZE, BUFFERS)
|
|---|
| 226 | SELECT * FROM active_prescriptions_for_pet WHERE medicine_id = 47;
|
|---|
| 227 |
|
|---|
| 228 | -- INSERT into prescription, prescription_medicine
|
|---|
| 229 | INSERT INTO prescription (examination_id, date_start, date_end, description)
|
|---|
| 230 | VALUES (699, CURRENT_DATE, CURRENT_DATE + 10, 'Antibiotic course, 10 days');
|
|---|
| 231 | -- SELECT max(id) FROM prescription;
|
|---|
| 232 |
|
|---|
| 233 | INSERT INTO prescription_medicine (prescription_id, medicine_id, dosage, num_days)
|
|---|
| 234 | VALUES (432525, 1, 250, 10);
|
|---|
| 235 |
|
|---|
| 236 | -- UPDATE on prescription, prescription_medicine
|
|---|
| 237 | UPDATE prescription
|
|---|
| 238 | SET date_end = date_end + 5
|
|---|
| 239 | WHERE id = 328;
|
|---|
| 240 |
|
|---|
| 241 | UPDATE prescription_medicine
|
|---|
| 242 | SET dosage = 300
|
|---|
| 243 | WHERE prescription_id = 327 AND medicine_id = 8;
|
|---|
| 244 |
|
|---|
| 245 | -- CREATE INDEX idx_prescription_active_dates ON prescription (date_end, date_start);
|
|---|
| 246 | DROP INDEX IF EXISTS idx_prescription_active_dates;
|
|---|
| 247 |
|
|---|
| 248 | -- INSERT into prescription, prescription_medicine
|
|---|
| 249 | INSERT INTO prescription (examination_id, date_start, date_end, description)
|
|---|
| 250 | VALUES (700, CURRENT_DATE, CURRENT_DATE + 7, 'Follow-up course');
|
|---|
| 251 | -- SELECT max(id) FROM prescription;
|
|---|
| 252 |
|
|---|
| 253 | INSERT INTO prescription_medicine (prescription_id, medicine_id, dosage, num_days)
|
|---|
| 254 | VALUES (432526, 2, 200, 7);
|
|---|
| 255 |
|
|---|
| 256 | -- UPDATE on prescription, prescription_medicine
|
|---|
| 257 | UPDATE prescription
|
|---|
| 258 | SET date_end = date_end + 3
|
|---|
| 259 | WHERE id = 329;
|
|---|
| 260 |
|
|---|
| 261 | UPDATE prescription_medicine
|
|---|
| 262 | SET dosage = 150
|
|---|
| 263 | WHERE prescription_id = 329 AND medicine_id = 6756;
|
|---|
| 264 |
|
|---|
| 265 | -- ============================================================
|
|---|
| 266 | -- View 4: employee_performance_summary
|
|---|
| 267 | --
|
|---|
| 268 | -- Primary filter: employee_id (also usable by date_treatment range)
|
|---|
| 269 | -- Use case: management pulls a per-employee workload record.
|
|---|
| 270 | -- Every examination they conducted, every treatment tied to it,
|
|---|
| 271 | -- and what that treatment was billed at in order to review caseload
|
|---|
| 272 | -- and revenue contribution per vet/assistant.
|
|---|
| 273 | -- ============================================================
|
|---|
| 274 |
|
|---|
| 275 | -- DROP VIEW IF EXISTS employee_performance_summary;
|
|---|
| 276 |
|
|---|
| 277 | CREATE MATERIALIZED VIEW employee_performance_summary AS
|
|---|
| 278 | SELECT
|
|---|
| 279 | emp.id AS employee_id,
|
|---|
| 280 | emp.first_name || ' ' || emp.last_name AS employee_name,
|
|---|
| 281 | rl.name AS employee_role,
|
|---|
| 282 | e.id AS examination_id,
|
|---|
| 283 | e.date_examination,
|
|---|
| 284 | e.status AS examination_status,
|
|---|
| 285 | t.id AS treatment_id,
|
|---|
| 286 | tt.name AS treatment_type,
|
|---|
| 287 | t.date_treatment,
|
|---|
| 288 | ii.price AS billed_price,
|
|---|
| 289 | ii.invoice_id
|
|---|
| 290 | FROM employee emp
|
|---|
| 291 | JOIN role rl ON rl.id = emp.role_id
|
|---|
| 292 | LEFT JOIN examination e ON e.employee_id = emp.id
|
|---|
| 293 | LEFT JOIN treatment t ON t.examination_id = e.id
|
|---|
| 294 | LEFT JOIN treatment_type tt ON tt.id = t.treatment_type_id
|
|---|
| 295 | LEFT JOIN invoice_item ii ON ii.treatment_id = t.id;
|
|---|
| 296 |
|
|---|
| 297 | SELECT * FROM employee_performance_summary WHERE employee_id = 5;
|
|---|
| 298 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM employee_performance_summary WHERE employee_id = 5;
|
|---|
| 299 |
|
|---|
| 300 | SELECT * FROM employee_performance_summary
|
|---|
| 301 | WHERE employee_id = 5 AND date_treatment >= '2025-01-01' AND date_treatment < '2026-01-01';
|
|---|
| 302 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM employee_performance_summary
|
|---|
| 303 | WHERE employee_id = 5 AND date_treatment >= '2025-01-01' AND date_treatment < '2026-01-01';
|
|---|
| 304 |
|
|---|
| 305 | --INSERT into examination
|
|---|
| 306 | INSERT INTO examination(date_examination, status, description, appointment_id, employee_id, examination_room_id)
|
|---|
| 307 | VALUES ('2026-08-01','completed','Regular check-up', 720800,6,3);
|
|---|
| 308 |
|
|---|
| 309 | --INSERT into treatment
|
|---|
| 310 | INSERT INTO treatment(date_treatment, notes, treatment_type_id, examination_id)
|
|---|
| 311 | VALUES ('2026-08-01','Follow-up plan agreed',2,715);
|
|---|
| 312 |
|
|---|
| 313 | --INSERT into invoice
|
|---|
| 314 | INSERT INTO invoice(date_invoice, total, coupon_id, owner_id)
|
|---|
| 315 | VALUES ('2026-08-01',56.33,398,79);
|
|---|
| 316 |
|
|---|
| 317 | --INSERT into invoice_item
|
|---|
| 318 | INSERT INTO invoice_item(num_item, invoice_id, price,quantity, type, shop_item_id, treatment_id)
|
|---|
| 319 | VALUES (1,24972,67.87,1,'treatment',null,223433);
|
|---|
| 320 |
|
|---|
| 321 | --UPDATE on treatment
|
|---|
| 322 | UPDATE treatment
|
|---|
| 323 | SET notes = 'Updated: discussed follow-up diet plan'
|
|---|
| 324 | WHERE id = 5778001;
|
|---|
| 325 |
|
|---|
| 326 | CREATE INDEX idx_treatment_examination ON treatment (examination_id);
|
|---|
| 327 | -- CREATE INDEX idx_treatment_date ON treatment (date_treatment);
|
|---|
| 328 | -- CREATE INDEX idx_invoice_item_treatment ON invoice_item (treatment_id);
|
|---|
| 329 | DROP INDEX IF EXISTS idx_treatment_date;
|
|---|
| 330 | DROP INDEX IF EXISTS idx_invoice_item_treatment;
|
|---|
| 331 |
|
|---|
| 332 | -- INSERT into examination (second follow-up)
|
|---|
| 333 | INSERT INTO examination(date_examination, status, description, appointment_id, employee_id, examination_room_id)
|
|---|
| 334 | VALUES ('2026-08-01','completed','Follow-up check-up', 720800,6,3);
|
|---|
| 335 |
|
|---|
| 336 | --INSERT into treatment (second follow-up)
|
|---|
| 337 | INSERT INTO treatment(date_treatment, notes, treatment_type_id, examination_id)
|
|---|
| 338 | VALUES ('2026-08-01','Follow-up plan discussed',2,715);
|
|---|
| 339 |
|
|---|
| 340 | UPDATE treatment
|
|---|
| 341 | SET notes = 'Updated after second follow-up'
|
|---|
| 342 | WHERE id = 5778002;
|
|---|
| 343 |
|
|---|
| 344 | -- ============================================================
|
|---|
| 345 | -- View 5: invoice_billing_details
|
|---|
| 346 | --
|
|---|
| 347 | -- Primary filter: invoice_id (also works by owner_id)
|
|---|
| 348 | -- Use case: front-desk/billing staff pull up everything on an
|
|---|
| 349 | -- invoice — owner, coupon applied, every line item (shop item
|
|---|
| 350 | -- or treatment), and payments received, to answer the question "what does
|
|---|
| 351 | -- this owner still owe" or reprint a receipt.
|
|---|
| 352 | -- ============================================================
|
|---|
| 353 |
|
|---|
| 354 | CREATE OR REPLACE VIEW invoice_billing_details AS
|
|---|
| 355 | SELECT
|
|---|
| 356 | i.id AS invoice_id,
|
|---|
| 357 | i.date_invoice,
|
|---|
| 358 | i.total AS invoice_total,
|
|---|
| 359 | o.id AS owner_id,
|
|---|
| 360 | o.first_name || ' ' || o.last_name AS owner_name,
|
|---|
| 361 | o.phone AS owner_phone,
|
|---|
| 362 | c.code AS coupon_code,
|
|---|
| 363 | c.type AS coupon_type,
|
|---|
| 364 | c.value AS coupon_value,
|
|---|
| 365 | ii.num_item,
|
|---|
| 366 | ii.type AS line_type,
|
|---|
| 367 | ii.price AS line_price,
|
|---|
| 368 | ii.quantity,
|
|---|
| 369 | si.name AS shop_item_name,
|
|---|
| 370 | tr.id AS treatment_id,
|
|---|
| 371 | tt.name AS treatment_type,
|
|---|
| 372 | p.date_payment,
|
|---|
| 373 | p.amount AS amount_paid,
|
|---|
| 374 | p.method AS payment_method
|
|---|
| 375 | FROM invoice i
|
|---|
| 376 | JOIN owner o ON o.id = i.owner_id
|
|---|
| 377 | LEFT JOIN coupon c ON c.id = i.coupon_id
|
|---|
| 378 | LEFT JOIN invoice_item ii ON ii.invoice_id = i.id
|
|---|
| 379 | LEFT JOIN shop_item si ON si.id = ii.shop_item_id
|
|---|
| 380 | LEFT JOIN treatment tr ON tr.id = ii.treatment_id
|
|---|
| 381 | LEFT JOIN treatment_type tt ON tt.id = tr.treatment_type_id
|
|---|
| 382 | LEFT JOIN payment p ON p.invoice_id = i.id;
|
|---|
| 383 |
|
|---|
| 384 | SELECT * FROM invoice_billing_details WHERE invoice_id = 500000;
|
|---|
| 385 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM invoice_billing_details WHERE invoice_id = 500000;
|
|---|
| 386 |
|
|---|
| 387 | SELECT * FROM invoice_billing_details WHERE owner_id = 45;
|
|---|
| 388 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM invoice_billing_details WHERE owner_id = 45;
|
|---|
| 389 |
|
|---|
| 390 | -- INSERT into invoice
|
|---|
| 391 | INSERT INTO invoice (date_invoice, total, coupon_id, owner_id)
|
|---|
| 392 | VALUES (CURRENT_DATE, 62.50, NULL, 8);
|
|---|
| 393 |
|
|---|
| 394 | -- INSERT into invoice_item
|
|---|
| 395 | INSERT INTO invoice_item (num_item, invoice_id, price,quantity, type, shop_item_id, treatment_id)
|
|---|
| 396 | VALUES (1, 24984,62.50, 1, 'shop_item', 9,null);
|
|---|
| 397 |
|
|---|
| 398 | -- INSERT into payment
|
|---|
| 399 | INSERT INTO payment (date_payment, amount, method, invoice_id)
|
|---|
| 400 | VALUES (CURRENT_DATE, 62.50, 'credit card', 24984);
|
|---|
| 401 |
|
|---|
| 402 | -- UPDATE on invoice
|
|---|
| 403 | UPDATE invoice
|
|---|
| 404 | SET total = 58.00
|
|---|
| 405 | WHERE id = 24984;
|
|---|
| 406 |
|
|---|
| 407 | -- UPDATE on payment
|
|---|
| 408 | UPDATE payment
|
|---|
| 409 | SET amount = 58.00
|
|---|
| 410 | WHERE invoice_id = 24984;
|
|---|
| 411 |
|
|---|
| 412 | --Creating indexes
|
|---|
| 413 | CREATE INDEX idx_invoice_owner ON invoice (owner_id);
|
|---|
| 414 | CREATE INDEX idx_payment_invoice ON payment (invoice_id);
|
|---|
| 415 | -- CREATE INDEX idx_invoice_item_invoice_id ON invoice_item (invoice_id, num_item);
|
|---|
| 416 | DROP INDEX IF EXISTS idx_invoice_item_invoice_id;
|
|---|
| 417 |
|
|---|
| 418 |
|
|---|
| 419 | -- INSERT into invoice (second invoice)
|
|---|
| 420 | INSERT INTO invoice (date_invoice, total, coupon_id, owner_id)
|
|---|
| 421 | VALUES (CURRENT_DATE, 69.50, NULL, 8);
|
|---|
| 422 |
|
|---|
| 423 | -- INSERT into invoice_item (second invoice)
|
|---|
| 424 | INSERT INTO invoice_item (num_item, invoice_id, price,quantity, type, shop_item_id, treatment_id)
|
|---|
| 425 | VALUES (1, 24984,69.50, 1, 'shop_item', 9,null);
|
|---|
| 426 |
|
|---|
| 427 | -- INSERT into payment (second invoice)
|
|---|
| 428 | INSERT INTO payment (date_payment, amount, method, invoice_id)
|
|---|
| 429 | VALUES (CURRENT_DATE, 50.00, 'credit card', 24984);
|
|---|
| 430 |
|
|---|
| 431 | UPDATE invoice
|
|---|
| 432 | SET total = 27.00
|
|---|
| 433 | WHERE id = 24984;
|
|---|
| 434 |
|
|---|
| 435 | -- ============================================================
|
|---|
| 436 | -- View 6: low_stock_shop_items
|
|---|
| 437 | --
|
|---|
| 438 | -- Primary filter: category_name (also usable by a stock threshold)
|
|---|
| 439 | -- Use case: shop manager checks what needs reordering. Any item
|
|---|
| 440 | -- with fewer than 20 units left, grouped by category so they
|
|---|
| 441 | -- can restock by supplier/category in one trip.
|
|---|
| 442 | -- ============================================================
|
|---|
| 443 |
|
|---|
| 444 | CREATE OR REPLACE VIEW low_stock_shop_items AS
|
|---|
| 445 | SELECT
|
|---|
| 446 | si.id AS shop_item_id,
|
|---|
| 447 | si.name AS item_name,
|
|---|
| 448 | si.price,
|
|---|
| 449 | si.stock,
|
|---|
| 450 | sic.id AS category_id,
|
|---|
| 451 | sic.name AS category_name,
|
|---|
| 452 | parent.name AS parent_category_name
|
|---|
| 453 | FROM shop_item si
|
|---|
| 454 | JOIN shop_item_category sic ON sic.id = si.shop_item_category_id
|
|---|
| 455 | LEFT JOIN shop_item_category parent ON parent.id = sic.parent_id
|
|---|
| 456 | WHERE si.stock < 20;
|
|---|
| 457 |
|
|---|
| 458 | SELECT * FROM low_stock_shop_items WHERE category_name = 'Medicine';
|
|---|
| 459 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM low_stock_shop_items WHERE category_name = 'Medicine';
|
|---|
| 460 |
|
|---|
| 461 | SELECT * FROM low_stock_shop_items WHERE stock < 10;
|
|---|
| 462 | EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM low_stock_shop_items WHERE stock < 10;
|
|---|
| 463 |
|
|---|
| 464 | -- INSERT a new item that's already low on stock
|
|---|
| 465 | INSERT INTO shop_item (name, price, stock, shop_item_category_id)
|
|---|
| 466 | SELECT 'Emergency Saline Restock Pack', 12.99, 8, sic.id
|
|---|
| 467 | FROM shop_item_category sic
|
|---|
| 468 | WHERE sic.name = 'Medicine'
|
|---|
| 469 | LIMIT 1;
|
|---|
| 470 |
|
|---|
| 471 | -- UPDATE — simulate a sale reducing stock on an existing item
|
|---|
| 472 | UPDATE shop_item
|
|---|
| 473 | SET stock = stock - 5
|
|---|
| 474 | WHERE id = (SELECT id FROM shop_item WHERE name = 'Emergency Saline Restock Pack');
|
|---|
| 475 |
|
|---|
| 476 | -- second restock scenario
|
|---|
| 477 | UPDATE shop_item
|
|---|
| 478 | SET stock = stock - 3
|
|---|
| 479 | WHERE id = (SELECT id FROM shop_item WHERE name = 'Emergency Saline Restock Pack');
|
|---|
| 480 |
|
|---|
| 481 | INSERT INTO shop_item (name, price, stock, shop_item_category_id)
|
|---|
| 482 | SELECT 'Sample Low-Stock Toy', 6.49, 4, sic.id
|
|---|
| 483 | FROM shop_item_category sic
|
|---|
| 484 | WHERE sic.name = 'Toys'
|
|---|
| 485 | LIMIT 1; |
|---|