| 71 | | JOIN course_translate ct ON c.id = ct.course_id AND ct.language = 'en' |
| 72 | | JOIN course_version cv ON c.id = cv.course_id |
| 73 | | JOIN enrollment e ON cv.id = e.course_version_id |
| 74 | | JOIN payment p ON e.id = p.enrollment_id AND p.payment_status = 'COMPLETED' |
| 75 | | LEFT JOIN review r ON e.id = r.enrollment_id |
| | 73 | JOIN course_translate ct ON c.course_id = ct.course_id |
| | 74 | JOIN language l ON l.id = ct.language_id AND l.value = 'en' |
| | 75 | JOIN course_version cv ON c.course_id = cv.course_id |
| | 76 | JOIN enrollment e ON cv.course_version_id = e.course_version_id |
| | 77 | JOIN payment p ON e.enrollment_id = p.enrollment_id AND p.payment_status = 'completed' |
| | 78 | LEFT JOIN review r ON e.enrollment_id = r.enrollment_id |
| 117 | | cv.active::BOOLEAN AS is_version_active, |
| 118 | | COUNT(e.id)::BIGINT AS total_enrollments, |
| 119 | | COUNT(CASE WHEN p.payment_status = 'COMPLETED' THEN e.id END)::BIGINT AS paid_enrollments, |
| 120 | | COUNT(CASE WHEN e.purchase_date IS NULL THEN e.id END)::BIGINT AS trial_enrollments, |
| 121 | | COUNT(CASE WHEN e.completion_date IS NOT NULL THEN e.id END)::BIGINT AS total_completions, |
| | 121 | cv.is_active::BOOLEAN AS is_version_active, |
| | 122 | COUNT(e.enrollment_id)::BIGINT AS total_enrollments, |
| | 123 | COUNT(CASE WHEN p.payment_status = 'completed' THEN e.enrollment_id END)::BIGINT AS paid_enrollments, |
| | 124 | COUNT(CASE WHEN p.payment_id IS NULL THEN e.enrollment_id END)::BIGINT AS trial_enrollments, |
| | 125 | COUNT(CASE WHEN e.completion_date IS NOT NULL THEN e.enrollment_id END)::BIGINT AS total_completions, |
| 139 | | JOIN course_translate ct ON c.id = ct.course_id AND ct.language = 'en' |
| 140 | | JOIN course_version cv ON c.id = cv.course_id |
| 141 | | LEFT JOIN enrollment e ON cv.id = e.course_version_id -- left join to include versions with zero enrollments |
| 142 | | LEFT JOIN payment p ON e.id = p.enrollment_id -- left join to include enrollments without payments (because enrollment can be in trial) |
| 143 | | LEFT JOIN review r ON e.id = r.enrollment_id -- left join to include enrollments without reviews |
| 144 | | GROUP BY c.id, ct.id, cv.id |
| 145 | | HAVING COUNT(DISTINCT e.id) > 0 |
| | 143 | JOIN course_translate ct ON c.course_id = ct.course_id |
| | 144 | JOIN language l ON l.id = ct.language_id AND l.value = 'en' |
| | 145 | JOIN course_version cv ON c.course_id = cv.course_id |
| | 146 | LEFT JOIN enrollment e ON cv.course_version_id = e.course_version_id -- left join to include versions with zero enrollments |
| | 147 | LEFT JOIN payment p ON e.enrollment_id = p.enrollment_id -- left join to include enrollments without payments (because enrollment can be in trial) |
| | 148 | LEFT JOIN review r ON e.enrollment_id = r.enrollment_id -- left join to include enrollments without reviews |
| | 149 | GROUP BY c.course_id, ct.course_translate_id, cv.course_version_id |
| | 150 | HAVING COUNT(DISTINCT e.enrollment_id) > 0 |
| 168 | | ex.id::INTEGER AS expert_id, |
| 169 | | ex.name::TEXT, |
| 170 | | COUNT(DISTINCT c.id)::BIGINT AS courses_created, |
| 171 | | COUNT(DISTINCT e.id)::BIGINT AS total_enrollments, |
| 172 | | COUNT(DISTINCT CASE WHEN p.payment_status = 'COMPLETED' THEN e.id END)::BIGINT AS paid_enrollments, |
| 173 | | COUNT(DISTINCT CASE WHEN e.purchase_date IS NULL THEN e.id END)::BIGINT AS trial_enrollments, |
| 174 | | COALESCE(SUM(CASE WHEN p.payment_status = 'COMPLETED' THEN p.amount ELSE 0 END), 0)::NUMERIC AS total_revenue, |
| | 174 | ex.expert_id::INTEGER AS expert_id, |
| | 175 | a.name::TEXT AS expert_name, |
| | 176 | COUNT(DISTINCT c.course_id)::BIGINT AS courses_created, |
| | 177 | COUNT(DISTINCT e.enrollment_id)::BIGINT AS total_enrollments, |
| | 178 | COUNT(DISTINCT CASE WHEN p.payment_status = 'completed' THEN e.enrollment_id END)::BIGINT AS paid_enrollments, |
| | 179 | COUNT(DISTINCT CASE WHEN p.payment_id IS NULL THEN e.enrollment_id END)::BIGINT AS trial_enrollments, |
| | 180 | COALESCE(SUM(CASE WHEN p.payment_status = 'completed' THEN p.amount ELSE 0 END), 0)::NUMERIC AS total_revenue, |
| 178 | | LEFT JOIN expert_course ec ON ex.id = ec.expert_id -- experts with no courses should be included |
| 179 | | LEFT JOIN course c ON ec.course_id = c.id -- experts with no courses should be included |
| 180 | | JOIN course_version cv ON c.id = cv.course_id -- only courses with versions (which is always the case) |
| 181 | | LEFT JOIN enrollment e ON cv.id = e.course_version_id -- left join to include courses with zero enrollments |
| 182 | | LEFT JOIN payment p ON e.id = p.enrollment_id -- left join to include enrollments without payments |
| 183 | | LEFT JOIN review r ON e.id = r.enrollment_id -- left join to include enrollments without reviews |
| 184 | | GROUP BY ex.id |
| | 184 | JOIN account a ON a.id = ex.account_id -- expert name lives on account |
| | 185 | LEFT JOIN expert_course ec ON ex.expert_id = ec.expert_id -- experts with no courses should be included |
| | 186 | LEFT JOIN course c ON ec.course_id = c.course_id -- experts with no courses should be included |
| | 187 | LEFT JOIN course_version cv ON c.course_id = cv.course_id -- left join so experts without courses are not dropped |
| | 188 | LEFT JOIN enrollment e ON cv.course_version_id = e.course_version_id -- left join to include courses with zero enrollments |
| | 189 | LEFT JOIN payment p ON e.enrollment_id = p.enrollment_id -- left join to include enrollments without payments |
| | 190 | LEFT JOIN review r ON e.enrollment_id = r.enrollment_id -- left join to include enrollments without reviews |
| | 191 | GROUP BY ex.expert_id, a.id |
| 206 | 213 | π year, month, course_id, course_name, course_description, course_difficulty, course_price, version_number, is_version_active, total_paid_enrollments, total_students, total_revenue, total_reviews, average_rating ( |
| 207 | 214 | τ year DESC, month DESC, total_revenue DESC, total_students DESC ( |
| 224 | | course ⋈ id = course_id ∧ language = 'en' course_translate |
| 225 | | ⋈ id = course_id course_version |
| 226 | | ⋈ id = course_version_id enrollment |
| 227 | | ⋈ id = enrollment_id ∧ payment_status = 'COMPLETED' payment |
| 228 | | ⟕ id = enrollment_id review |
| | 231 | course ⋈ course_id = course_id course_translate |
| | 232 | ⋈ language_id = id ∧ value = 'en' language |
| | 233 | ⋈ course_id = course_id course_version |
| | 234 | ⋈ course_version_id = course_version_id enrollment |
| | 235 | ⋈ enrollment_id = enrollment_id ∧ payment_status = 'completed' payment |
| | 236 | ⟕ enrollment_id = enrollment_id review |
| 234 | 242 | π course_id, course_name, course_description, course_difficulty, course_price, version_number, is_version_active, total_enrollments, paid_enrollments, trial_enrollments, total_completions, total_students, total_revenue, average_rating, total_reviews, avg_days_to_complete, completion_rate_percentage, avg_lecture_completion_percentage ( |
| 235 | 243 | τ total_revenue DESC, completion_rate_percentage DESC ( |
| 244 | | is_version_active ← cv.active, |
| 245 | | total_enrollments ← COUNT(e.id), |
| 246 | | paid_enrollments ← COUNT(CASE WHEN payment_status = 'COMPLETED' THEN e.id END), |
| 247 | | trial_enrollments ← COUNT(CASE WHEN purchase_date IS NULL THEN e.id END), |
| 248 | | total_completions ← COUNT(CASE WHEN completion_date IS NOT NULL THEN e.id END), |
| | 252 | is_version_active ← cv.is_active, |
| | 253 | total_enrollments ← COUNT(e.enrollment_id), |
| | 254 | paid_enrollments ← COUNT(CASE WHEN payment_status = 'completed' THEN e.enrollment_id END), |
| | 255 | trial_enrollments ← COUNT(CASE WHEN payment_id IS NULL THEN e.enrollment_id END), |
| | 256 | total_completions ← COUNT(CASE WHEN completion_date IS NOT NULL THEN e.enrollment_id END), |
| 252 | | total_reviews ← COUNT(r.id), |
| 253 | | avg_days_to_complete ← ROUND(AVG(CASE WHEN completion_date IS NOT NULL THEN EXTRACT(EPOCH FROM completion_date - activation_date) / 86400 END), 0), |
| 254 | | completion_rate_percentage ← ROUND(100.0 * COUNT(CASE WHEN completion_date IS NOT NULL THEN e.id END) / NULLIF(COUNT(e.id), 0), 2), |
| 255 | | avg_lecture_completion_percentage ← ROUND(AVG(COALESCE((SELECT COUNT(CASE WHEN completed = true THEN 1 END) * 100.0 / NULLIF(COUNT(*), 0) FROM user_course_progress WHERE enrollment_id = e.id), 0)), 2) |
| | 260 | total_reviews ← COUNT(r.review_id), |
| | 261 | avg_days_to_complete ← ROUND(AVG(CASE WHEN completion_date IS NOT NULL THEN completion_date - activation_date END), 0), |
| | 262 | completion_rate_percentage ← ROUND(100.0 * COUNT(CASE WHEN completion_date IS NOT NULL THEN e.enrollment_id END) / NULLIF(COUNT(e.enrollment_id), 0), 2), |
| | 263 | avg_lecture_completion_percentage ← ROUND(AVG(COALESCE((SELECT COUNT(CASE WHEN is_completed = true THEN 1 END) * 100.0 / NULLIF(COUNT(*), 0) FROM user_course_progress WHERE enrollment_id = e.enrollment_id), 0)), 2) |
| 257 | | course ⋈ id = course_id ∧ language = 'en' course_translate |
| 258 | | ⋈ id = course_id course_version |
| 259 | | ⟕ id = course_version_id enrollment |
| 260 | | ⟕ id = enrollment_id payment |
| 261 | | ⟕ id = enrollment_id review |
| | 265 | course ⋈ course_id = course_id course_translate |
| | 266 | ⋈ language_id = id ∧ value = 'en' language |
| | 267 | ⋈ course_id = course_id course_version |
| | 268 | ⟕ course_version_id = course_version_id enrollment |
| | 269 | ⟕ enrollment_id = enrollment_id payment |
| | 270 | ⟕ enrollment_id = enrollment_id review |
| 268 | | π expert_id, name, courses_created, total_enrollments, paid_enrollments, trial_enrollments, total_revenue, avg_rating, total_reviews ( |
| | 277 | π expert_id, expert_name, courses_created, total_enrollments, paid_enrollments, trial_enrollments, total_revenue, avg_rating, total_reviews ( |
| 270 | | γ ex.id; |
| 271 | | expert_id ← ex.id, |
| 272 | | name ← ex.name, |
| 273 | | courses_created ← COUNT(DISTINCT c.id), |
| 274 | | total_enrollments ← COUNT(DISTINCT e.id), |
| 275 | | paid_enrollments ← COUNT(DISTINCT CASE WHEN payment_status = 'COMPLETED' THEN e.id END), |
| 276 | | trial_enrollments ← COUNT(DISTINCT CASE WHEN purchase_date IS NULL THEN e.id END), |
| 277 | | total_revenue ← COALESCE(SUM(CASE WHEN payment_status = 'COMPLETED' THEN amount ELSE 0 END), 0), |
| | 279 | γ ex.expert_id, a.id; |
| | 280 | expert_id ← ex.expert_id, |
| | 281 | expert_name ← a.name, |
| | 282 | courses_created ← COUNT(DISTINCT c.course_id), |
| | 283 | total_enrollments ← COUNT(DISTINCT e.enrollment_id), |
| | 284 | paid_enrollments ← COUNT(DISTINCT CASE WHEN payment_status = 'completed' THEN e.enrollment_id END), |
| | 285 | trial_enrollments ← COUNT(DISTINCT CASE WHEN payment_id IS NULL THEN e.enrollment_id END), |
| | 286 | total_revenue ← COALESCE(SUM(CASE WHEN payment_status = 'completed' THEN amount ELSE 0 END), 0), |
| 282 | | ⟕ id = expert_id expert_course |
| 283 | | ⟕ course_id = id course |
| 284 | | ⋈ id = course_id course_version |
| 285 | | ⟕ id = course_version_id enrollment |
| 286 | | ⟕ id = enrollment_id payment |
| 287 | | ⟕ id = enrollment_id review |
| | 291 | ⋈ account_id = id account |
| | 292 | ⟕ expert_id = expert_id expert_course |
| | 293 | ⟕ course_id = course_id course |
| | 294 | ⟕ course_id = course_id course_version |
| | 295 | ⟕ course_version_id = course_version_id enrollment |
| | 296 | ⟕ enrollment_id = enrollment_id payment |
| | 297 | ⟕ enrollment_id = enrollment_id review |