| | 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 | }}} |