-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathqueries_db_script.py
More file actions
163 lines (147 loc) · 4.41 KB
/
Copy pathqueries_db_script.py
File metadata and controls
163 lines (147 loc) · 4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import mysql.connector
from tabulate import tabulate
# -DATABASE CONFIGURATION
DB_CONFIG = {
'user': '****',
'password': '****',
'host': '****',
'database': '****',
'port': 3305,
'raise_on_warnings': True,
'use_pure': True,
'connection_timeout': 10
}
# establish the database connection
def get_connection():
return mysql.connector.connect(**DB_CONFIG)
# --- Query 1: Full-Text Search on Title
def query_1(keyword):
"""
Search movies containing a specific keyword in their title
return their name, release date and meta_score.
"""
q = f"""
SELECT
title, release_date, meta_score
FROM
Movie
WHERE
MATCH(title) AGAINST('{keyword}');
"""
return q
# --- Query 2: Full-Text Search on Staff Name
def query_2(keyword):
"""
filter movies by searched staff member.
include the movie title, staff member name and his role in the film.
results sorted first by actor name and then by movie title.
"""
q = f"""
SELECT
SM.person_name AS actor_name,
M.title AS movie_title,
SM.role AS actor_role
FROM
Movie M
JOIN
Staff_Movie SM ON M.movie_id = SM.movie_id
WHERE
MATCH(SM.person_name) AGAINST('%{keyword}%')
ORDER BY
SM.person_name, movie_title;
"""
return q
# --- Query 3: complex (Group By + Aggregation)
def query_3():
"""
Find the total revenue generated by movies grouped by their release year.
Sorted by year ascending.
"""
q = """
SELECT
YEAR(release_date) AS release_year,
SUM(revenue) AS total_revenue
FROM
Movie
WHERE release_date IS NOT NULL
GROUP BY
release_year
ORDER BY
release_year ASC;
"""
return q
# --- Query 4: Complex (Nested Query + Group By + Having)
def query_4():
"""
Find actors whose movies have an average rating higher than the global average,
displaying their name, average rating (rounded to 2 decimals) and the global average rating.
"""
q = """
SELECT
SM.person_name AS actor_name,
ROUND(AVG(M.average_rating), 2) AS actor_avg_rating,
ROUND((SELECT AVG(average_rating) FROM Movie), 2) AS global_avg_rating
FROM
Staff_Movie SM
JOIN
Movie M ON SM.movie_id = M.movie_id
WHERE
SM.role = 'actor'
GROUP BY
SM.person_name
HAVING
actor_avg_rating > global_avg_rating
ORDER BY
actor_avg_rating DESC
LIMIT
20;
"""
return q
# --- Query 5: Complex (Exists + Case + Join)
def query_5():
"""
Find movies with a budget greater than $100M and produced in multiple languages.
Including a Boolean column (available_in_Arabic) indicating whether each movie is available in Arabic.
The results are sorted by budget in descending order.
"""
q = """
SELECT
M.title AS movie_title,
M.budget,
COUNT(ML.language_name) AS number_of_languages,
CASE
WHEN EXISTS (SELECT 1 FROM Movie_Language ML2 WHERE ML2.movie_id = M.movie_id AND ML2.language_name = 'Arabic')
THEN 'yes'
ELSE 'no'
END AS available_in_Arabic
FROM
Movie M
JOIN
Movie_Language ML ON M.movie_id = ML.movie_id
WHERE
M.budget > 100000000
GROUP BY
M.movie_id
HAVING
number_of_languages > 1
ORDER BY
M.budget DESC;
"""
return q
def execute_query(query, prnt=False):
"""
Executes the input query string.
If prnt == True: prints the results using tabulate.
"""
con = get_connection()
cursor = con.cursor()
cursor.execute(query)
results = cursor.fetchall()
if prnt:
# Get column names from cursor description
if cursor.description:
headers = [x[0] for x in cursor.description]
print(tabulate(results, headers=headers, tablefmt="grid"))
cursor.close()
con.close()
return results