| 1 | === Оптимизиран SQL-код, кој работи поедноставно и побрзо |
| 2 | |
| 3 | {{{ |
| 4 | create table account( |
| 5 | id serial primary key, |
| 6 | username varchar(255) not null, |
| 7 | email varchar(255) not null, |
| 8 | password varchar(255) not null, |
| 9 | balance decimal(15, 2) not null |
| 10 | ); |
| 11 | |
| 12 | create table "transaction"( |
| 13 | id serial primary key, |
| 14 | amount decimal(15, 2) not null, |
| 15 | currency varchar(255) not null, |
| 16 | type varchar(50) not null, |
| 17 | timestamp timestamp default current_timestamp, |
| 18 | account_id int not null, |
| 19 | foreign key (account_id) references account(id) |
| 20 | ); |
| 21 | |
| 22 | create table transfer( |
| 23 | id serial primary key, |
| 24 | s_id int not null, |
| 25 | r_id int not null, |
| 26 | foreign key(s_id) references account(id), |
| 27 | foreign key(r_id) references |
| 28 | account(id) |
| 29 | |
| 30 | ); |
| 31 | |
| 32 | create table deposit( |
| 33 | id serial primary key, |
| 34 | account_id int not null, |
| 35 | amount decimal(15,2) not null, |
| 36 | timestamp timestamp default current_timestamp, |
| 37 | foreign key(account_id) references account(id) |
| 38 | ); |
| 39 | |
| 40 | create table withdraw( |
| 41 | id serial primary key, |
| 42 | account_id int not null, |
| 43 | amount decimal(15,2) not null, |
| 44 | timestamp timestamp default current_timestamp, |
| 45 | foreign key(account_id) references account(id) |
| 46 | ); |
| 47 | |
| 48 | create table transferred_money( |
| 49 | id serial primary key, |
| 50 | s_account_id int not null, |
| 51 | r_account_id int not null, |
| 52 | t_id int not null, |
| 53 | currency varchar(50) not null, |
| 54 | foreign key (s_account_id) references account(id), |
| 55 | foreign key (r_account_id) references account(id), |
| 56 | foreign key (t_id) references transaction(id) |
| 57 | ); |
| 58 | |
| 59 | create or replace function after_transaction_trigger() |
| 60 | returns trigger as $$ |
| 61 | begin |
| 62 | |
| 63 | if new.type = 'Deposit' then |
| 64 | insert into Deposit(account_id,amount, timestamp) |
| 65 | values (new.account_id, new.amount, new.timestamp); |
| 66 | |
| 67 | elsif new.type = 'Withdrawal' then |
| 68 | insert into Withdraw(account_id,amount, timestamp) |
| 69 | values (new.account_id, new.amount, new.timestamp); |
| 70 | |
| 71 | elsif new.type like '(MKD) Transfer Out to%' then |
| 72 | insert into transferred_money(s_account_id, r_account_id, t_id, currency) |
| 73 | select new.account_id, (select id from account where username = trim(substring(new.type from position('Transfer Out to ' in new.type)+15)) limit 1), |
| 74 | new.id, new.currency; |
| 75 | |
| 76 | elsif new.type like '(USD) Transfer Out to%' then |
| 77 | insert into transferred_money(s_account_id, r_account_id, t_id, currency) |
| 78 | select new.account_id, (select id from account where username = trim(substring(new.type from position('Transfer Out to ' in new.type)+15)) limit 1), |
| 79 | new.id, new.currency; |
| 80 | |
| 81 | elsif new.type like '(EUR) Transfer Out to%' then |
| 82 | insert into transferred_money(s_account_id, r_account_id, t_id, currency) |
| 83 | select new.account_id, (select id from account where username = trim(substring(new.type from position('Transfer Out to ' in new.type)+15)) limit 1), |
| 84 | new.id, new.currency; |
| 85 | |
| 86 | elsif new.type like '(GBP) Transfer Out to%' then |
| 87 | insert into transferred_money(s_account_id, r_account_id, t_id, currency) |
| 88 | select new.account_id, (select id from account where username = trim(substring(new.type from position('Transfer Out to ' in new.type)+15)) limit 1), |
| 89 | new.id, new.currency; |
| 90 | |
| 91 | end if; |
| 92 | return new; |
| 93 | end; |
| 94 | $$ language plpgsql; |
| 95 | |
| 96 | create trigger after_transaction |
| 97 | after insert on transaction |
| 98 | for each row |
| 99 | execute function after_transaction_trigger(); |
| 100 | |
| 101 | |
| 102 | CREATE OR REPLACE FUNCTION after_transaction_trigger2() |
| 103 | RETURNS TRIGGER AS $$ |
| 104 | BEGIN |
| 105 | IF NEW.type = 'Deposit' THEN |
| 106 | -- Log deposit as a self-transfer |
| 107 | INSERT INTO transfer(s_id, r_id) |
| 108 | VALUES (NEW.account_id, NEW.account_id); |
| 109 | |
| 110 | ELSIF NEW.type = 'Withdrawal' THEN |
| 111 | -- Log withdrawal as a self-transfer |
| 112 | INSERT INTO transfer(s_id, r_id) |
| 113 | VALUES (NEW.account_id, NEW.account_id); |
| 114 | |
| 115 | ELSIF NEW.type LIKE '(MKD) Transfer Out to%' OR |
| 116 | NEW.type LIKE '(USD) Transfer Out to%' OR |
| 117 | NEW.type LIKE '(EUR) Transfer Out to%' OR |
| 118 | NEW.type LIKE '(GBP) Transfer Out to%' THEN |
| 119 | |
| 120 | -- Extract recipient username and insert into transfer table |
| 121 | INSERT INTO transfer(s_id, r_id) |
| 122 | SELECT NEW.account_id, |
| 123 | (SELECT id FROM account |
| 124 | WHERE username = TRIM(SUBSTRING(NEW.type FROM POSITION('Transfer Out to ' IN NEW.type) + 15)) |
| 125 | LIMIT 1); |
| 126 | |
| 127 | END IF; |
| 128 | |
| 129 | RETURN NEW; |
| 130 | END; |
| 131 | $$ LANGUAGE plpgsql; |
| 132 | |
| 133 | CREATE TRIGGER after_transaction2 |
| 134 | AFTER INSERT ON transaction |
| 135 | FOR EACH ROW |
| 136 | EXECUTE FUNCTION after_transaction_trigger2(); |
| 137 | |
| 138 | |
| 139 | |
| 140 | select * from account; |
| 141 | select * from "transaction"; |
| 142 | select * from transfer; |
| 143 | select * from transferred_money; |
| 144 | select * from deposit; |
| 145 | select * from withdraw; |
| 146 | |
| 147 | SELECT |
| 148 | tm.s_account_id AS sender_id, |
| 149 | a_s.username AS sender_username, |
| 150 | tm.r_account_id AS receiver_id, |
| 151 | a_r.username AS receiver_username, |
| 152 | tm.t_id, |
| 153 | t.timestamp, |
| 154 | t.amount |
| 155 | |
| 156 | FROM |
| 157 | transferred_money tm |
| 158 | JOIN |
| 159 | account a_s ON tm.s_account_id = a_s.id |
| 160 | JOIN |
| 161 | account a_r ON tm.r_account_id = a_r.id |
| 162 | JOIN |
| 163 | "transaction" t ON tm.t_id = t.id; |
| 164 | |
| 165 | |
| 166 | SELECT |
| 167 | tm.s_account_id AS sender_id, |
| 168 | a_s.username AS sender_username, |
| 169 | tm.r_account_id AS receiver_id, |
| 170 | a_r.username AS receiver_username, |
| 171 | tm.t_id, |
| 172 | t.timestamp, |
| 173 | t.amount |
| 174 | |
| 175 | FROM |
| 176 | transferred_money tm |
| 177 | JOIN |
| 178 | account a_s ON tm.s_account_id = a_s.id |
| 179 | JOIN |
| 180 | account a_r ON tm.r_account_id = a_r.id |
| 181 | JOIN |
| 182 | "transaction" t ON tm.t_id = t.id |
| 183 | WHERE |
| 184 | timestamp<'2025-03-23 20:30:00.000000'; |
| 185 | |
| 186 | SELECT |
| 187 | tm.s_account_id AS sender_id, |
| 188 | a_s.username AS sender_username, |
| 189 | tm.r_account_id AS receiver_id, |
| 190 | a_r.username AS receiver_username, |
| 191 | tm.t_id, |
| 192 | t.timestamp, |
| 193 | t.amount, |
| 194 | tm.currency |
| 195 | |
| 196 | FROM |
| 197 | transferred_money tm |
| 198 | JOIN |
| 199 | account a_s ON tm.s_account_id = a_s.id |
| 200 | JOIN |
| 201 | account a_r ON tm.r_account_id = a_r.id |
| 202 | JOIN |
| 203 | "transaction" t ON tm.t_id = t.id |
| 204 | WHERE tm.currency='(EUR)' |
| 205 | ORDER BY timestamp; |
| 206 | |
| 207 | SELECT |
| 208 | max(t.amount) as maximum, |
| 209 | avg(t.amount) as "average", |
| 210 | min(t.amount) as minimum |
| 211 | |
| 212 | FROM |
| 213 | transferred_money tm |
| 214 | JOIN |
| 215 | account a_s ON tm.s_account_id = a_s.id |
| 216 | JOIN |
| 217 | account a_r ON tm.r_account_id = a_r.id |
| 218 | JOIN |
| 219 | "transaction" t ON tm.t_id = t.id |
| 220 | WHERE tm.currency='(USD)'; |
| 221 | |
| 222 | }}} |