| | 1 | = Complex DB Reports (SQL, Stored Procedures, Relational Algebra) |
| | 2 | |
| | 3 | |
| | 4 | === 1. Story Statistics |
| | 5 | |
| | 6 | ==== SQL |
| | 7 | {{{ |
| | 8 | |
| | 9 | WITH likeCount AS ( |
| | 10 | SELECT |
| | 11 | story_id, |
| | 12 | COUNT(user_id) AS total_likes |
| | 13 | FROM likes |
| | 14 | GROUP BY story_id |
| | 15 | ), |
| | 16 | commentCount AS ( |
| | 17 | SELECT |
| | 18 | story_id, |
| | 19 | COUNT(comment_id) AS total_comments |
| | 20 | FROM comment |
| | 21 | GROUP BY story_id |
| | 22 | ), |
| | 23 | averageRating AS ( |
| | 24 | SELECT |
| | 25 | story_id, |
| | 26 | ROUND(AVG(rating), 2) AS avg_rating |
| | 27 | FROM chapter |
| | 28 | WHERE rating IS NOT NULL |
| | 29 | GROUP BY story_id |
| | 30 | ) |
| | 31 | SELECT |
| | 32 | u.username AS writer, |
| | 33 | s.story_id, |
| | 34 | s.short_description, |
| | 35 | st.status, |
| | 36 | COALESCE(lk.total_likes, 0) AS total_likes, |
| | 37 | COALESCE(cm.total_comments, 0) AS total_comments, |
| | 38 | COALESCE(CAST(ar.avg_rating AS VARCHAR), 'no ratings') AS avg_rating |
| | 39 | FROM story s |
| | 40 | JOIN status st ON s.story_id = st.story_id |
| | 41 | JOIN writer w ON s.user_id = w.user_id |
| | 42 | JOIN users u ON w.user_id = u.user_id |
| | 43 | LEFT JOIN likeCount lk ON s.story_id = lk.story_id |
| | 44 | LEFT JOIN commentCount cm ON s.story_id = cm.story_id |
| | 45 | LEFT JOIN averageRating ar ON s.story_id = ar.story_id |
| | 46 | ORDER BY total_likes DESC, total_comments DESC; |
| | 47 | }}} |
| | 48 | |
| | 49 | ==== Relational Algebra |
| | 50 | {{{ |
| | 51 | likeCount <- |
| | 52 | γ story_id; |
| | 53 | total_likes := COUNT(user_id) |
| | 54 | ( |
| | 55 | likes |
| | 56 | ) |
| | 57 | |
| | 58 | commentCount <- |
| | 59 | γ story_id; |
| | 60 | total_comments := COUNT(comment_id) |
| | 61 | ( |
| | 62 | comment |
| | 63 | ) |
| | 64 | |
| | 65 | averageRating <- |
| | 66 | γ story_id; |
| | 67 | avg_rating := ROUND(AVG(rating), 2) |
| | 68 | ( |
| | 69 | σ rating ≠ NULL (chapter) |
| | 70 | ) |
| | 71 | |
| | 72 | Base <- |
| | 73 | story s |
| | 74 | ⨝ (s.story_id = st.story_id) status st |
| | 75 | ⨝ (s.user_id = w.user_id) writer w |
| | 76 | ⨝ (w.user_id = u.user_id) users u |
| | 77 | |
| | 78 | WithLikes <- |
| | 79 | Base |
| | 80 | ⟕ (s.story_id = lk.story_id) likeCount lk |
| | 81 | |
| | 82 | WithComments <- |
| | 83 | WithLikes |
| | 84 | ⟕ (s.story_id = cm.story_id) commentCount cm |
| | 85 | |
| | 86 | WithRatings <- |
| | 87 | WithComments |
| | 88 | ⟕ (s.story_id = ar.story_id) averageRating ar |
| | 89 | |
| | 90 | Result <- |
| | 91 | π |
| | 92 | u.username → writer, |
| | 93 | s.story_id, |
| | 94 | s.short_description, |
| | 95 | st.status, |
| | 96 | COALESCE(lk.total_likes, 0) → total_likes, |
| | 97 | COALESCE(cm.total_comments, 0) → total_comments, |
| | 98 | COALESCE(ar.avg_rating, 'no ratings') → avg_rating |
| | 99 | ( |
| | 100 | WithRatings |
| | 101 | ) |
| | 102 | }}} |