DatabaseCreation: views.sql

File views.sql, 11.5 KB (added by 235013, 11 days ago)
Line 
1-- =============================================================================
2-- VIEW 1: Contract details (base view)
3-- =============================================================================
4-- Contract details with both parties resolved.
5CREATE OR REPLACE VIEW vw_contract_details AS
6SELECT cvc.contract_id,
7 cvc.contract_number,
8 cvc.contract_title,
9 cvc.start_date,
10 cvc.end_date,
11 cvc.total_value,
12 cvc.currency_code,
13 cvc.is_active,
14 c.client_id,
15 c.company_name,
16 v.vendor_id,
17 v.agency_name
18FROM Client_Vendor_Contract cvc
19 JOIN Client c ON c.client_id = cvc.client_id
20 JOIN Vendor v ON v.vendor_id = cvc.vendor_id;
21
22
23-- =============================================================================
24-- VIEW 2: Project details (base view)
25-- =============================================================================
26-- Shared project details for the reporting views: the project with its
27-- status, its contract and both parties.
28CREATE OR REPLACE VIEW vw_project_details AS
29SELECT p.project_id,
30 p.project_name,
31 p.status_id,
32 ps.status_name,
33 p.start_date,
34 p.end_date,
35 p.budget,
36 cd.contract_id,
37 cd.contract_number,
38 cd.currency_code,
39 cd.client_id,
40 cd.company_name,
41 cd.vendor_id,
42 cd.agency_name
43FROM Project p
44 JOIN vw_contract_details cd ON cd.contract_id = p.contract_id
45 JOIN Project_Status ps ON ps.status_id = p.status_id;
46
47
48-- =============================================================================
49-- VIEW 3: All projects per Vendor
50-- =============================================================================
51CREATE OR REPLACE VIEW vw_projects_per_vendor AS
52SELECT pd.vendor_id,
53 pd.agency_name,
54 pd.project_id,
55 pd.project_name,
56 pd.status_name,
57 pd.start_date,
58 pd.end_date,
59 pd.budget,
60 pd.currency_code
61FROM vw_project_details pd
62ORDER BY pd.agency_name, pd.status_name, pd.project_name;
63
64
65-- =============================================================================
66-- VIEW 4: All projects per Client
67-- =============================================================================
68CREATE OR REPLACE VIEW vw_projects_per_client AS
69SELECT pd.client_id,
70 pd.company_name,
71 pd.project_id,
72 pd.project_name,
73 pd.status_name,
74 pd.start_date,
75 pd.end_date,
76 pd.budget,
77 pd.currency_code
78FROM vw_project_details pd
79ORDER BY pd.company_name, pd.status_name, pd.project_name;
80
81
82-- =============================================================================
83-- VIEW 5: Budget summary per Vendor
84-- =============================================================================
85CREATE OR REPLACE VIEW vw_budget_per_vendor AS
86SELECT pd.vendor_id,
87 pd.agency_name,
88 pd.currency_code,
89 COUNT(pd.project_id) AS project_count,
90 SUM(pd.budget) AS total_budget
91FROM vw_project_details pd
92GROUP BY pd.vendor_id, pd.agency_name, pd.currency_code
93ORDER BY pd.agency_name, pd.currency_code;
94
95
96-- =============================================================================
97-- VIEW 6: Budget summary per Client
98-- =============================================================================
99CREATE OR REPLACE VIEW vw_budget_per_client AS
100SELECT pd.client_id,
101 pd.company_name,
102 pd.currency_code,
103 COUNT(pd.project_id) AS project_count,
104 SUM(pd.budget) AS total_budget
105FROM vw_project_details pd
106GROUP BY pd.client_id, pd.company_name, pd.currency_code
107ORDER BY pd.company_name, pd.currency_code;
108
109
110-- =============================================================================
111-- VIEW 7: List of Clients per Industry
112-- =============================================================================
113CREATE OR REPLACE VIEW vw_clients_per_industry AS
114SELECT i.industry_id,
115 i.industry_name,
116 c.client_id,
117 c.company_name,
118 c.contact_email
119FROM Client c
120 JOIN Industry i ON i.industry_id = c.industry_id
121ORDER BY i.industry_name, c.company_name;
122
123
124-- =============================================================================
125-- VIEW 8: Average rating per Vendor (across all rating dimensions)
126-- =============================================================================
127-- Aggregates the scores of published reviews. Vendors without a scored
128-- published review stay in the result with review_count = 0 and
129-- avg_rating = NULL.
130-- The scores are summed and counted per review first; the vendor average
131-- SUM(score_sum) / SUM(score_cnt) is the same score-weighted mean as
132-- AVG(score_value) over all of the vendor's scores, and each scored review
133-- is counted once without a COUNT(DISTINCT).
134CREATE OR REPLACE VIEW vw_avg_rating_per_vendor AS
135SELECT v.vendor_id,
136 v.agency_name,
137 COUNT(vr.review_id) AS review_count,
138 ROUND(SUM(vr.score_sum) / NULLIF(SUM(vr.score_cnt), 0), 2) AS avg_rating
139FROM Vendor v
140 LEFT JOIN (SELECT pd.vendor_id,
141 r.review_id,
142 SUM(rs.score_value)::numeric AS score_sum,
143 COUNT(*) AS score_cnt
144 FROM Review r
145 JOIN Review_Score rs ON rs.review_id = r.review_id
146 JOIN vw_project_details pd ON pd.project_id = r.project_id
147 WHERE r.is_published = true
148 GROUP BY pd.vendor_id, r.review_id) vr ON vr.vendor_id = v.vendor_id
149GROUP BY v.vendor_id, v.agency_name
150ORDER BY avg_rating DESC NULLS LAST;
151
152
153-- =============================================================================
154-- VIEW 9: All unresolved Dispute Tickets
155-- =============================================================================
156-- The vendor columns identify the agency of the filing user.
157CREATE OR REPLACE VIEW vw_unresolved_dispute_tickets AS
158SELECT dt.ticket_id,
159 dt.filed_at,
160 dt.reason,
161 r.review_id,
162 p.project_id,
163 p.project_name,
164 dt.vendor_user_id AS filed_by_vendor_user_id,
165 vusr.first_name || ' ' || vusr.last_name AS filed_by_vendor_user,
166 dt.assigned_management_user_id,
167 musr.first_name || ' ' || musr.last_name AS assigned_to_management_user,
168 dt.created_at,
169 dt.updated_at,
170 ven.vendor_id,
171 ven.agency_name
172FROM Dispute_Ticket dt
173 JOIN Review r ON r.review_id = dt.review_id
174 JOIN Project p ON p.project_id = r.project_id
175 JOIN Vendor_User vu ON vu.user_id = dt.vendor_user_id
176 JOIN Vendor ven ON ven.vendor_id = vu.vendor_id
177 JOIN "User" vusr ON vusr.user_id = vu.user_id
178 LEFT JOIN "User" musr ON musr.user_id = dt.assigned_management_user_id
179WHERE dt.is_resolved = false
180ORDER BY dt.filed_at;
181
182
183-- =============================================================================
184-- VIEW 10: Project count per Status per Vendor
185-- =============================================================================
186CREATE OR REPLACE VIEW vw_project_count_by_status_per_vendor AS
187SELECT pd.vendor_id,
188 pd.agency_name,
189 pd.status_id,
190 pd.status_name,
191 COUNT(pd.project_id) AS project_count
192FROM vw_project_details pd
193GROUP BY pd.vendor_id, pd.agency_name, pd.status_id, pd.status_name
194ORDER BY pd.agency_name, pd.status_name;
195
196
197-- =============================================================================
198-- VIEW 11: Project count per Status per Client
199-- =============================================================================
200CREATE OR REPLACE VIEW vw_project_count_by_status_per_client AS
201SELECT pd.client_id,
202 pd.company_name,
203 pd.status_id,
204 pd.status_name,
205 COUNT(pd.project_id) AS project_count
206FROM vw_project_details pd
207GROUP BY pd.client_id, pd.company_name, pd.status_id, pd.status_name
208ORDER BY pd.company_name, pd.status_name;
209
210
211-- =============================================================================
212-- VIEW 12: Contracts per Vendor
213-- =============================================================================
214CREATE OR REPLACE VIEW vw_contracts_per_vendor AS
215SELECT cd.vendor_id,
216 cd.agency_name,
217 cd.contract_id,
218 cd.contract_number,
219 cd.contract_title,
220 cd.client_id,
221 cd.company_name AS client_name,
222 cd.start_date,
223 cd.end_date,
224 cd.total_value,
225 cd.currency_code,
226 cd.is_active
227FROM vw_contract_details cd
228ORDER BY cd.agency_name, cd.is_active DESC, cd.start_date DESC;
229
230
231-- =============================================================================
232-- VIEW 13: Contracts per Client
233-- =============================================================================
234CREATE OR REPLACE VIEW vw_contracts_per_client AS
235SELECT cd.client_id,
236 cd.company_name,
237 cd.contract_id,
238 cd.contract_number,
239 cd.contract_title,
240 cd.vendor_id,
241 cd.agency_name AS vendor_name,
242 cd.start_date,
243 cd.end_date,
244 cd.total_value,
245 cd.currency_code,
246 cd.is_active
247FROM vw_contract_details cd
248ORDER BY cd.company_name, cd.is_active DESC, cd.start_date DESC;
249
250
251-- =============================================================================
252-- VIEW 14: Vendor subscription status
253-- =============================================================================
254CREATE OR REPLACE VIEW vw_vendor_subscriptions AS
255SELECT v.vendor_id,
256 v.agency_name,
257 st.tier_id,
258 st.tier_name,
259 COALESCE(vs.negotiated_price, st.list_price, 0) AS effective_price,
260 vs.start_date,
261 vs.end_date,
262 vs.is_active
263FROM Vendor_Subscription vs
264 JOIN Vendor v ON v.vendor_id = vs.vendor_id
265 JOIN Subscription_Tier st ON st.tier_id = vs.tier_id
266ORDER BY v.agency_name, vs.is_active DESC, vs.start_date DESC;
267
268
269-- =============================================================================
270-- VIEW 15: Rating per Vendor broken down by rating dimension
271-- =============================================================================
272-- Per-dimension scores from published reviews.
273CREATE OR REPLACE VIEW vw_vendor_rating_by_dimension AS
274SELECT pd.vendor_id,
275 pd.agency_name,
276 rd.dimension_id,
277 rd.dimension_name,
278 COUNT(*) AS score_count,
279 ROUND(AVG(rs.score_value), 2) AS avg_score,
280 MIN(rs.score_value) AS min_score,
281 MAX(rs.score_value) AS max_score
282FROM Review_Score rs
283 JOIN Rating_Dimension rd ON rd.dimension_id = rs.dimension_id
284 JOIN Review r ON r.review_id = rs.review_id
285 JOIN vw_project_details pd ON pd.project_id = r.project_id
286WHERE r.is_published = true
287GROUP BY pd.vendor_id, pd.agency_name, rd.dimension_id, rd.dimension_name;
288
289
290-- =============================================================================
291-- VIEW 16: Budget changes per Project (the budget audit trail)
292-- =============================================================================
293-- One row per recorded budget change; delta and pct_change are derived here.
294CREATE OR REPLACE VIEW vw_project_budget_changes AS
295SELECT pba.audit_id,
296 pd.project_id,
297 pd.project_name,
298 pd.vendor_id,
299 pd.client_id,
300 pd.currency_code,
301 pba.old_budget,
302 pba.new_budget,
303 pba.new_budget - pba.old_budget AS delta,
304 ROUND(100.0 * (pba.new_budget - pba.old_budget) / NULLIF(pba.old_budget, 0), 1) AS pct_change,
305 pba.created_at AS changed_at
306FROM Project_Budget_Audit pba
307 JOIN vw_project_details pd ON pd.project_id = pba.project_id;