| 24 | == Материјализирани views |
| 25 | |
| 26 | Напредните извештаи од минатите фази се искористени за да се направат materialized views. Материјализираните views значително го намалуваат времето на извршување на квери поради тоа што го чуваат и резултатот. Ова е соодветно поради тоа што ваквите статистики нема потреба да бидат up to date во секој момент, доволно е да се рефрешираат на одреден период (на пример 12 часа). |
| 27 | |
| 28 | Во продолжение се прикажани материјалиизираните views (за некои од нив има и графици кои може да се погледнат во амин панелот). |
| 29 | |
| 30 | ==== Средна разлика на простигнување на инстанците од постојка А до постојка Б |
| 31 | |
| 32 | Идејата е да може да се има естимација на време за кое автобусот би стигнал на одредена постојка. |
| 33 | |
| 34 | {{{#!div |
| 35 | {{{#!sql |
| 36 | |
| 37 | CREATE MATERIALIZED VIEW avg_time_diffs AS |
| 38 | WITH ordered_instanca AS (SELECT ilpl.instanca_na_linija_id, |
| 39 | ilpl.postojka_na_linija_id, |
| 40 | pnl.reden_broj, |
| 41 | ilpl.timestamp |
| 42 | FROM instanca_na_linija_postojka_na_linija ilpl |
| 43 | JOIN |
| 44 | postojka_na_linija pnl ON ilpl.postojka_na_linija_id = pnl.id |
| 45 | ORDER BY ilpl.instanca_na_linija_id, |
| 46 | pnl.reden_broj), |
| 47 | time_differences AS (SELECT o1.instanca_na_linija_id, |
| 48 | o1.postojka_na_linija_id AS start_station_id, |
| 49 | o1.timestamp AS start_time, |
| 50 | o2.postojka_na_linija_id AS end_station_id, |
| 51 | o2.timestamp AS end_time, |
| 52 | EXTRACT(EPOCH FROM (o2.timestamp - o1.timestamp)) AS time_diff |
| 53 | FROM ordered_instanca o1 |
| 54 | JOIN |
| 55 | ordered_instanca o2 ON o1.instanca_na_linija_id = o2.instanca_na_linija_id |
| 56 | WHERE o1.reden_broj + 1 = o2.reden_broj) |
| 57 | SELECT |
| 58 | row_number() over () as id, |
| 59 | start_station_id, |
| 60 | end_station_id, |
| 61 | AVG(time_diff)::double precision AS avg_time_diff_seconds |
| 62 | FROM time_differences |
| 63 | GROUP BY start_station_id, |
| 64 | end_station_id |
| 65 | ORDER BY start_station_id, |
| 66 | end_station_id; |
| 67 | |
| 68 | create unique index avg_time_diffs_index on avg_time_diffs (id); |
| 69 | |
| 70 | |
| 71 | }}} |
| 72 | }}} |
| 73 | |
| 74 | ==== Број на казни според линија |
| 75 | |
| 76 | {{{#!div |
| 77 | {{{#!sql |
| 78 | |
| 79 | create materialized view kazna_po_linija as |
| 80 | select row_number() over () as id, l.id as line_id, count(l.id) |
| 81 | from linija l |
| 82 | left join instanca_na_linija inl on l.id = inl.linija_id |
| 83 | left join kontrola k on inl.id = k.instanca_na_linija_id |
| 84 | left join kazna kaz on k.id = kaz.kontrola_id |
| 85 | where extract(year from kaz.date_created) = extract(year from now()) |
| 86 | group by l.id |
| 87 | order by count(l.id) desc; |
| 88 | |
| 89 | create unique index index_kazna_po_linija on kazna_po_linija(id); |
| 90 | |
| 91 | }}} |
| 92 | }}} |
| 93 | |
| 94 | |
| 95 | ==== Зафатеност на линиите по интервали од 1 час |
| 96 | |
| 97 | {{{#!div |
| 98 | {{{#!sql |
| 99 | |
| 100 | create materialized view most_busy_part_of_the_day as |
| 101 | select row_number() over () as id, id as linija_id, interval_1h, count(id || '-' || interval_1h) broj_pati |
| 102 | from (select li.id, |
| 103 | (to_char(extract(hour from v.start_date), '00') || ':00 -' || to_char(extract(hour from (v.start_date |
| 104 | + '1 hours'::interval))::int, '00') || ':00') as interval_1h |
| 105 | from linija li |
| 106 | left join instanca_na_linija inl on li.id = inl.linija_id |
| 107 | left join vozenje v on inl.id = v.instanca_na_linija_id |
| 108 | where v.start_date between (make_date(extract(year from (now()))::int, 1, 1)) and (make_date(extract(year from (now()))::int, 12, 31))) as hours |
| 109 | group by id, interval_1h |
| 110 | order by interval_1h desc; |
| 111 | |
| 112 | create unique index index_most_busy_part_of_the_day on most_busy_part_of_the_day(id); |
| 113 | |
| 114 | }}} |
| 115 | }}} |
| 116 | |
| 117 | ==== Commutes per line |
| 118 | |
| 119 | {{{#!sql |
| 120 | create materialized view commutes_by_line as |
| 121 | select row_number() over () as id, l.id as linija_id, count(v.id) |
| 122 | from linija l |
| 123 | left join instanca_na_linija inl on l.id = inl.linija_id |
| 124 | left join vozenje v on inl.id = v.instanca_na_linija_id |
| 125 | where v.start_date between date_trunc('year', now()) and date_trunc('month', date_trunc('year', now())+ interval '7 months') |
| 126 | group by l.id; |
| 127 | }}} |
| 128 | |
| 129 | ==== Number of passengers per line and station |
| 130 | |
| 131 | {{#!sql |
| 132 | create materialized view number_passengers_per_line_and_station as |
| 133 | select row_number() over () as id, p.id as station_id, l.id as line_id, count(p.id) |
| 134 | from postojka p |
| 135 | join postojka_na_linija pnl on p.id = pnl.postojka_id |
| 136 | join vozenje v on pnl.id = v.postojka_na_linija_start_id |
| 137 | join patnik pat on v.patnik_id = pat.id |
| 138 | join linija l on pnl.linija_id = l.id |
| 139 | where v.start_date between (make_date(extract(year from (now() - '1 years'::interval))::int, 4, 1)) and (make_date(extract(year from (now() - '1 years'::interval))::int, 6, 30)) |
| 140 | group by p.id, l.id |
| 141 | order by count(p.id) desc; |
| 142 | }} |
| 143 | |
| 144 | ==== Ticket sales |
| 145 | |
| 146 | {{{#!sql |
| 147 | create materialized view ticket_sales as |
| 148 | select row_number() over () as id, filtered.tip_id, filtered.interval_1h, filtered.broj_pati |
| 149 | from (select filter.tip_id, interval_1h, count(tip_id || '-' || interval_1h) broj_pati |
| 150 | from (select *, |
| 151 | (to_char(extract(hour from b.datum_kupuvanje), '00') || ':00 -' || |
| 152 | to_char(extract(hour from (b.datum_kupuvanje + '1 hours'::interval))::int, '00') || |
| 153 | ':00') as interval_1h |
| 154 | from tipbilet t |
| 155 | left join bilet b on t.id = b.tip_id |
| 156 | -- where b.datum_kupuvanje between (make_date(extract(year from (now() - '1 years'::interval))::int, 1, 1)) and (make_date(extract(year from (now() - '1 years'::interval))::int, 12, 31)) |
| 157 | |
| 158 | ) as filter |
| 159 | group by filter.tip_id, interval_1h) filtered |
| 160 | where broj_pati = (select max(filtered.broj_pati) |
| 161 | from (select filter.tip_id, interval_1h, count(tip_id || '-' || interval_1h) broj_pati |
| 162 | from (select *, |
| 163 | (to_char(extract(hour from b.datum_kupuvanje), '00') || ':00 -' || |
| 164 | to_char(extract(hour from (b.datum_kupuvanje + '1 hours'::interval))::int, |
| 165 | '00') || |
| 166 | ':00') as interval_1h |
| 167 | from tipbilet t |
| 168 | left join bilet b on t.id = b.tip_id |
| 169 | -- where b.datum_kupuvanje between (make_date(extract(year from (now() - '1 years'::interval))::int, 1, 1)) and (make_date(extract(year from (now() - '1 years'::interval))::int, 12, 31)) |
| 170 | |
| 171 | ) as filter |
| 172 | group by filter.tip_id, interval_1h) filtered) |
| 173 | and tip_id in (select id |
| 174 | from tipbilet |
| 175 | where ime in ('Hourly', 'Daily')); |
| 176 | }}} |
| 177 | |
| 178 | ==== Total income (from ticket sales and fines) |
| 179 | |
| 180 | {{{#!sql |
| 181 | create materialized view total_income as |
| 182 | WITH kazna_sum AS ( |
| 183 | SELECT |
| 184 | EXTRACT(YEAR FROM k.date_payed) AS year, |
| 185 | SUM(k.iznos) AS sum_kz |
| 186 | FROM |
| 187 | kazna k |
| 188 | WHERE |
| 189 | k.plateno = TRUE |
| 190 | GROUP BY |
| 191 | EXTRACT(YEAR FROM k.date_payed) |
| 192 | ), |
| 193 | bilet_sum AS ( |
| 194 | SELECT |
| 195 | EXTRACT(YEAR FROM b.datum_kupuvanje) AS year, |
| 196 | SUM(tb.cena) AS sum_b |
| 197 | FROM |
| 198 | bilet b |
| 199 | JOIN tipbilet tb ON tb.id = b.tip_id |
| 200 | GROUP BY |
| 201 | EXTRACT(YEAR FROM b.datum_kupuvanje) |
| 202 | ) |
| 203 | SELECT |
| 204 | row_number() over () as id, |
| 205 | COALESCE(k.year, b.year)::text AS year, |
| 206 | COALESCE(sum_kz, 0) as fines_income, |
| 207 | COALESCE(sum_b, 0) as ticket_income, |
| 208 | COALESCE(sum_kz, 0) + COALESCE(sum_b, 0) AS total_income |
| 209 | FROM |
| 210 | kazna_sum k |
| 211 | FULL OUTER JOIN bilet_sum b ON k.year = b.year |
| 212 | ORDER BY |
| 213 | year desc; |
| 214 | }}} |