6 | | === 1. Извештај за вкупни приходи на изнајмувачите на недвижности за нивните изнајмени единици како и просечен приход остварен по изнајмена единица во тековната година. |
7 | | {{{ |
8 | | SELECT |
9 | | u.first_name, |
10 | | u.last_name, |
11 | | u.email, |
12 | | u.rating, |
13 | | lp.is_agent, |
14 | | COUNT(DISTINCT l.id) AS lease_count, |
15 | | COUNT(DISTINCT l.tenant_id) AS tenant_count, |
16 | | COALESCE(SUM(p.amount), 0) AS total_revenue, |
17 | | ROUND( |
18 | | CASE WHEN COUNT(DISTINCT l.id) > 0 |
19 | | THEN COALESCE(SUM(p.amount), 0) / COUNT(DISTINCT l.id) |
20 | | ELSE 0 |
21 | | END, 2 |
22 | | ) AS avg_revenue_per_lease |
23 | | FROM LandlordProfile lp |
24 | | JOIN UserD u ON u.id = lp.id |
25 | | JOIN Lease l ON lp.id = l.landlord_id |
26 | | LEFT JOIN Payment p |
27 | | ON p.lease_id = l.id |
28 | | AND p.payment_date >= date_trunc('year', CURRENT_DATE) |
29 | | GROUP BY u.id, u.first_name, u.last_name, u.email, u.rating, lp.is_agent |
30 | | ORDER BY total_revenue DESC; |
31 | | }}} |
32 | | |
33 | | |
34 | | === 2. Извештај за перформансите на недвижностите по градови: број на имоти, број на издавачки единици, активни единици, остварени приходи за тековната година по град како и просечна кирија по изнајмувачка единица како и остварен приход по објект. |
35 | | |
36 | | {{{ |
37 | | SELECT |
38 | | a.city, |
39 | | COUNT(DISTINCT p.id) as total_properties, |
40 | | COUNT(DISTINCT u.id) as total_units, |
41 | | COUNT(DISTINCT l.id) as active_leases, |
42 | | SUM(pay.amount) as total_revenue, |
43 | | ROUND(AVG(l.rent_amount),2) as avg_rent_per_lease, |
44 | | ROUND (SUM(pay.amount) / COUNT(DISTINCT p.id),2) as revenue_per_property |
45 | | FROM Address a |
46 | | JOIN Property p ON a.id = p.address_id |
47 | | JOIN Unit u ON p.id = u.property_id |
48 | | JOIN Listing lst ON u.id = lst.unit_id |
49 | | JOIN Lease l ON lst.id = l.listing_id |
50 | | JOIN Payment pay ON l.id = pay.lease_id |
51 | | WHERE EXTRACT(YEAR FROM pay.payment_date) = EXTRACT(YEAR FROM CURRENT_DATE) |
52 | | AND pay.status = 'завршено' |
53 | | GROUP BY a.city |
54 | | ORDER BY total_revenue DESC; |
55 | | }}} |
56 | | |
57 | | === 3. Извештај за процент на изнајмени недвижности во однос на објавени огласи за секоја година. |
| 6 | === 1. Извештај за процент на изнајмени недвижности во однос на објавени огласи за секоја година. |
118 | | === 5. Извештај за цени за изнајмување на недвижности (просечна, минимална, максимална и цена по метар квадратен) согласно категорија на објект, град, број на соби, големина на објект. |
119 | | {{{ |
120 | | |
121 | | SELECT |
122 | | pt.name AS property_type, |
123 | | a.city, |
124 | | u.bedrooms, |
| 67 | === 3. Детален месечен извештај за приходите, наплатата, останатиот долг, ненаплатените и активните изнајмувања и нерешените сервисни барања на изнајмувачите |
| 68 | |
| 69 | |
| 70 | {{{ |
| 71 | WITH month_period AS ( |
| 72 | SELECT |
| 73 | DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1 month' AS month_start, |
| 74 | (DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1 month') + INTERVAL '1 month - 1 day' AS month_end |
| 75 | ), |
| 76 | landlords AS ( |
| 77 | SELECT lp.id AS landlord_id, u.first_name || ' ' || u.last_name AS landlord_name |
| 78 | FROM domify.LandlordProfile lp |
| 79 | JOIN domify.UserD u ON lp.id = u.id |
| 80 | ), |
| 81 | total_due_cte AS ( |
| 82 | SELECT |
| 83 | l.landlord_id, |
| 84 | COALESCE(SUM(l.rent_amount), 0) AS total_due |
| 85 | FROM domify.Lease l |
| 86 | CROSS JOIN month_period mp |
| 87 | WHERE l.start_date <= mp.month_end |
| 88 | AND l.end_date >= mp.month_start |
| 89 | GROUP BY l.landlord_id |
| 90 | ), |
| 91 | total_paid_cte AS ( |
| 92 | SELECT |
| 93 | l.landlord_id, |
| 94 | COALESCE(SUM(p.amount), 0) AS total_paid |
| 95 | FROM domify.Payment p |
| 96 | JOIN domify.Lease l ON p.lease_id = l.id |
| 97 | CROSS JOIN month_period mp |
| 98 | WHERE p.payment_date BETWEEN mp.month_start AND mp.month_end |
| 99 | AND p.status IN ('completed','paid') |
| 100 | GROUP BY l.landlord_id |
| 101 | ), |
| 102 | late_count_cte AS ( |
| 103 | SELECT |
| 104 | l.landlord_id, |
| 105 | COUNT(*) AS late_count |
| 106 | FROM domify.Lease l |
| 107 | CROSS JOIN month_period mp |
| 108 | WHERE l.start_date <= mp.month_end |
| 109 | AND l.end_date >= mp.month_start |
| 110 | AND NOT EXISTS ( |
| 111 | SELECT 1 |
| 112 | FROM domify.Payment p |
| 113 | WHERE p.lease_id = l.id |
| 114 | AND p.payment_date BETWEEN mp.month_start AND mp.month_end |
| 115 | AND p.status IN ('completed','paid') |
| 116 | ) |
| 117 | GROUP BY l.landlord_id |
| 118 | ), |
| 119 | active_leases_cte AS ( |
| 120 | SELECT |
| 121 | l.landlord_id, |
| 122 | COUNT(*) AS active_leases |
| 123 | FROM domify.Lease l |
| 124 | WHERE l.start_date <= CURRENT_DATE |
| 125 | AND l.end_date >= CURRENT_DATE |
| 126 | GROUP BY l.landlord_id |
| 127 | ), |
| 128 | pending_services_cte AS ( |
| 129 | SELECT |
| 130 | l.landlord_id, |
| 131 | COUNT(*) AS pending_services |
| 132 | FROM domify.ServiceRequest sr |
| 133 | JOIN domify.Lease l ON sr.lease_id = l.id |
| 134 | WHERE sr.status IN ('pending','in_progress') |
| 135 | GROUP BY l.landlord_id |
| 136 | ) |
| 137 | SELECT |
| 138 | ld.landlord_id, |
| 139 | ld.landlord_name, |
| 140 | td.total_due, |
| 141 | tp.total_paid, |
| 142 | (td.total_due - tp.total_paid) AS remaining_debt, |
| 143 | lc.late_count, |
| 144 | al.active_leases, |
| 145 | ps.pending_services |
| 146 | FROM landlords ld |
| 147 | CROSS JOIN month_period mp |
| 148 | LEFT JOIN total_due_cte td ON ld.landlord_id = td.landlord_id |
| 149 | LEFT JOIN total_paid_cte tp ON ld.landlord_id = tp.landlord_id |
| 150 | LEFT JOIN late_count_cte lc ON ld.landlord_id = lc.landlord_id |
| 151 | LEFT JOIN active_leases_cte al ON ld.landlord_id = al.landlord_id |
| 152 | LEFT JOIN pending_services_cte ps ON ld.landlord_id = ps.landlord_id |
| 153 | ORDER BY ld.landlord_name; |
| 154 | |
| 155 | }}} |
| 156 | === 4. Детален извештај за историјата на плаќања, задоцнети и тековни обврски, просечна кирија и оценка на платежната дисциплина на изнајмувачите |
| 157 | {{{ |
| 158 | WITH TenantPaymentStats AS ( |
| 159 | SELECT |
| 160 | t.id as tenant_id, |
| 161 | CONCAT(u.first_name, ' ', u.last_name) as tenant_name, |
| 162 | u.rating as tenant_rating, |
| 163 | COUNT(DISTINCT le.id) as total_leases, |
| 164 | COUNT(DISTINCT pay.id) as total_payments, |
| 165 | SUM(CASE WHEN pay.status = 'завршено' THEN pay.amount ELSE 0 END) as total_paid, |
| 166 | SUM(CASE WHEN pay.status = 'доцнење' THEN pay.amount ELSE 0 END) as late_payments_amount, |
| 167 | COUNT(CASE WHEN pay.status = 'доцнење' THEN 1 END) as late_payment_count, |
| 168 | COUNT(CASE WHEN pay.status = 'во тек' THEN 1 END) as pending_payment_count, |
| 169 | AVG(le.rent_amount) as avg_rent_amount, |
| 170 | MIN(le.start_date) as first_lease_date, |
| 171 | MAX(le.end_date) as latest_lease_end |
| 172 | FROM TenantProfile t |
| 173 | JOIN UserD u ON t.id = u.id |
| 174 | LEFT JOIN Lease le ON t.id = le.tenant_id |
| 175 | LEFT JOIN Payment pay ON le.id = pay.lease_id |
| 176 | GROUP BY t.id, u.first_name, u.last_name, u.rating |
| 177 | ) |
| 178 | SELECT |
| 179 | tenant_id, |
| 180 | tenant_name, |
| 181 | tenant_rating, |
| 182 | total_leases, |
| 183 | total_payments, |
| 184 | total_paid, |
| 185 | late_payments_amount, |
| 186 | late_payment_count, |
| 187 | pending_payment_count, |
| 188 | ROUND((late_payment_count * 100.0 / NULLIF(total_payments, 0)), 2) as late_payment_percentage, |
| 189 | avg_rent_amount, |
| 190 | first_lease_date, |
| 191 | latest_lease_end, |
126 | | WHEN u.area_sq_m < 50 THEN 'Мала (<50м²)' |
127 | | WHEN u.area_sq_m < 80 THEN 'Средна (50-80м²)' |
128 | | ELSE 'Голема (>80м²)' |
129 | | END AS size_category, |
130 | | COUNT(l.id) AS lease_count, |
131 | | ROUND(AVG(l.rent_amount), 2) AS avg_rent, |
132 | | ROUND(MIN(l.rent_amount), 2) AS min_rent, |
133 | | ROUND(MAX(l.rent_amount), 2) AS max_rent, |
134 | | ROUND(AVG(l.rent_amount / u.area_sq_m), 2) AS price_per_sqm |
135 | | FROM Lease l |
136 | | JOIN Listing li ON l.listing_id = li.id |
137 | | JOIN Unit u ON li.unit_id = u.id |
138 | | JOIN Property p ON u.property_id = p.id |
139 | | JOIN PropertyType pt ON p.property_type_id = pt.id |
140 | | JOIN Address a ON p.address_id = a.id |
141 | | WHERE l.start_date >= CURRENT_DATE - INTERVAL '12 months' |
142 | | GROUP BY pt.name, a.city, u.bedrooms, size_category |
143 | | HAVING COUNT(l.id) >= 1 |
144 | | ORDER BY a.city, pt.name, u.bedrooms; |
145 | | }}} |
146 | | |
147 | | === 6. Извештај за последната година за тоа колку просечно денови во секој месец огласите биле изложени пред да биде склучен договор за нив. |
148 | | {{{ |
149 | | SELECT |
150 | | EXTRACT(YEAR FROM li.available_from) AS year, |
151 | | EXTRACT(MONTH FROM li.available_from) AS month, |
152 | | COUNT(*) AS total_listings, |
153 | | AVG(l.start_date - li.available_from) AS avg_days_on_market |
154 | | FROM Listing li |
155 | | JOIN Lease l ON li.id = l.listing_id |
156 | | WHERE li.available_from >= CURRENT_DATE - INTERVAL '365 days' AND l.start_date BETWEEN li.available_from AND li.available_to |
157 | | GROUP BY year, month |
158 | | ORDER BY year, month; |
159 | | }}} |
160 | | |
161 | | === 7. Извештај за број на барања за поправка/сервисирање на недвижност по град |
162 | | {{{ |
163 | | SELECT |
164 | | a.city, |
165 | | COUNT(sr.id) AS request_count |
166 | | FROM ServiceRequest sr |
167 | | JOIN Lease l ON sr.lease_id = l.id |
168 | | JOIN Listing li ON l.listing_id = li.id |
169 | | JOIN Unit u ON li.unit_id = u.id |
170 | | JOIN Property p ON u.property_id = p.id |
171 | | JOIN Address a ON p.address_id = a.id |
172 | | WHERE EXTRACT(YEAR FROM sr.request_date) = EXTRACT(YEAR FROM CURRENT_DATE) |
173 | | GROUP BY a.city |
174 | | ORDER BY request_count DESC |
175 | | }}} |
176 | | |
177 | | === 8. Извештај за заинтересираност на изнајмувачи, издавачи со најмногу заинтересирани огласи сортирани по популарност |
178 | | |
179 | | {{{ |
180 | | SELECT |
181 | | u.first_name, |
182 | | u.last_name, |
183 | | u.email, |
184 | | a.city, |
185 | | COUNT(DISTINCT li.id) AS total_listings, |
186 | | COUNT(i.tenant_profile_id) AS total_interested_tenants, |
187 | | ROUND(COUNT(i.tenant_profile_id) / COUNT(DISTINCT li.id), 2) AS avg_interest_per_listing |
188 | | FROM LandlordProfile lp |
189 | | JOIN UserD u ON lp.id = u.id |
190 | | JOIN Property p ON p.owner_id = u.id |
191 | | JOIN Unit un ON un.property_id = p.id |
192 | | JOIN Listing li ON li.unit_id = un.id |
193 | | JOIN Address a ON p.address_id = a.id |
194 | | LEFT JOIN Interested i ON li.id = i.listing_id |
195 | | WHERE li.available_from >= CURRENT_DATE - INTERVAL '12 months' |
196 | | GROUP BY u.id, u.first_name, u.last_name, u.email, a.city |
197 | | HAVING COUNT(i.tenant_profile_id) > 0 |
198 | | ORDER BY total_interested_tenants DESC; |
199 | | }}} |
| 193 | WHEN late_payment_count = 0 THEN 'Одличен' |
| 194 | WHEN late_payment_count <= 2 THEN 'Добар' |
| 195 | WHEN late_payment_count <= 5 THEN 'Среден' |
| 196 | ELSE 'Ризичен' |
| 197 | END as payment_reliability_score |
| 198 | FROM TenantPaymentStats |
| 199 | WHERE total_leases > 0 |
| 200 | ORDER BY late_payment_percentage ASC, total_paid DESC; |
| 201 | |
| 202 | }}} |
| 203 | === 5. Детален извештај за сервисни барања, стапка на завршување и просечно време на решавање по општина и град |
| 204 | {{{ |
| 205 | WITH MaintenanceAnalysis AS ( |
| 206 | SELECT |
| 207 | a.municipality, |
| 208 | a.city, |
| 209 | sc.name as service_category, |
| 210 | COUNT(sr.id) as total_requests, |
| 211 | COUNT(CASE WHEN sr.status = 'завршено' THEN 1 END) as completed_requests, |
| 212 | COUNT(CASE WHEN sr.status = 'во тек' THEN 1 END) as in_progress_requests, |
| 213 | COUNT(CASE WHEN sr.status = 'во очекување' THEN 1 END) as pending_requests, |
| 214 | AVG(CASE |
| 215 | WHEN sr.status = 'завршено' AND ml.maintenance_date IS NOT NULL |
| 216 | THEN DATEDIFF(ml.maintenance_date, sr.request_date) |
| 217 | END) as avg_resolution_days |
| 218 | FROM ServiceRequest sr |
| 219 | JOIN ServiceCategory sc ON sr.service_category_id = sc.id |
| 220 | JOIN Lease le ON sr.lease_id = le.id |
| 221 | JOIN Listing l ON le.listing_id = l.id |
| 222 | JOIN Unit u ON l.unit_id = u.id |
| 223 | JOIN Property p ON u.property_id = p.id |
| 224 | JOIN Address a ON p.address_id = a.id |
| 225 | LEFT JOIN MaintenanceLog ml ON sr.id = ml.service_request_id |
| 226 | GROUP BY a.municipality, a.city, sc.name |
| 227 | ) |
| 228 | SELECT |
| 229 | municipality, |
| 230 | city, |
| 231 | service_category, |
| 232 | total_requests, |
| 233 | completed_requests, |
| 234 | in_progress_requests, |
| 235 | pending_requests, |
| 236 | ROUND((completed_requests * 100.0 / NULLIF(total_requests, 0)), 2) as completion_rate_percent, |
| 237 | ROUND(avg_resolution_days, 1) as avg_resolution_days, |
| 238 | CASE |
| 239 | WHEN avg_resolution_days <= 2 THEN 'Брзо' |
| 240 | WHEN avg_resolution_days <= 5 THEN 'Средно' |
| 241 | WHEN avg_resolution_days <= 10 THEN 'Бавно' |
| 242 | ELSE 'Многу бавно' |
| 243 | END as response_time_rating |
| 244 | FROM MaintenanceAnalysis |
| 245 | ORDER BY municipality, total_requests DESC; |
| 246 | |
| 247 | }}} |
| 248 | === 6.Анализа на пазарни трендови и изнајмувачка понуда по општина, град и тип на недвижност |
| 249 | {{{ |
| 250 | WITH MarketTrends AS ( |
| 251 | SELECT |
| 252 | a.municipality, |
| 253 | a.city, |
| 254 | pt.name as property_type, |
| 255 | COUNT(DISTINCT l.id) as total_listings, |
| 256 | COUNT(DISTINCT CASE WHEN l.status = 'available' THEN l.id END) as available_listings, |
| 257 | AVG(u.rent_amount) as avg_rent_asking, |
| 258 | AVG(le.rent_amount) as avg_rent_actual, |
| 259 | AVG(u.area_sq_m) as avg_unit_size, |
| 260 | AVG(u.rent_amount / u.area_sq_m) as avg_rent_per_sq_m, |
| 261 | MIN(u.rent_amount) as min_rent, |
| 262 | MAX(u.rent_amount) as max_rent, |
| 263 | COUNT(DISTINCT in_list.tenant_profile_id) as total_interested_tenants |
| 264 | FROM Address a |
| 265 | JOIN Property p ON a.id = p.address_id |
| 266 | JOIN PropertyType pt ON p.property_type_id = pt.id |
| 267 | JOIN Unit u ON p.id = u.property_id |
| 268 | JOIN Listing l ON u.id = l.unit_id |
| 269 | LEFT JOIN Lease le ON l.id = le.listing_id |
| 270 | LEFT JOIN Interested in_list ON l.id = in_list.listing_id |
| 271 | GROUP BY a.municipality, a.city, pt.name |
| 272 | ) |
| 273 | SELECT |
| 274 | municipality, |
| 275 | city, |
| 276 | property_type, |
| 277 | total_listings, |
| 278 | available_listings, |
| 279 | ROUND((available_listings * 100.0 / NULLIF(total_listings, 0)), 2) as availability_rate, |
| 280 | ROUND(avg_rent_asking, 2) as avg_rent_asking, |
| 281 | ROUND(avg_rent_actual, 2) as avg_rent_actual, |
| 282 | ROUND((avg_rent_actual - avg_rent_asking), 2) as rent_variance, |
| 283 | ROUND(avg_unit_size, 1) as avg_unit_size_sq_m, |
| 284 | ROUND(avg_rent_per_sq_m, 2) as avg_rent_per_sq_m, |
| 285 | min_rent, |
| 286 | max_rent, |
| 287 | total_interested_tenants, |
| 288 | ROUND(total_interested_tenants / NULLIF(available_listings, 0), 2) as interest_ratio, |
| 289 | CASE |
| 290 | WHEN availability_rate > 75 THEN 'Висока понуда' |
| 291 | WHEN availability_rate > 50 THEN 'Умерена понуда' |
| 292 | WHEN availability_rate > 25 THEN 'Ограничена понуда' |
| 293 | ELSE 'Ниска Понуда' |
| 294 | END as market_availability_status |
| 295 | FROM MarketTrends |
| 296 | WHERE total_listings > 0 |
| 297 | ORDER BY municipality, avg_rent_per_sq_m DESC; |
| 298 | |
| 299 | }}} |
| 300 | |