起初,我想为提供如此薄弱的头衔而道歉;我无法以更好的方式描述它。
请考虑以下事项:我们有三个表,一个用于users
,一个用于records
,另一个用于ratings
。这些表格不言自明,但数据库的架构如下:
+---------------------+
| Tables_in_relations |
+---------------------+
| records |
| ratings |
| users |
+---------------------+
records
表的架构如下:
+----------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------------------+------+-----+---------+----------------+
| id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
| title | varchar(256) | NO | | NULL | |
| year | int(4) | NO | | NULL | |
+----------+----------------------+------+-----+---------+----------------+
users
表的架构如下:
+----------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------------------+------+-----+---------+----------------+
| id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
| email | varchar(256) | NO | | NULL | |
| name | varchar(256) | NO | | NULL | |
| password | varchar(256) | NO | | NULL | |
+----------+----------------------+------+-----+---------+----------------+
ratings
表是obvoiusly,其中使用record_id和user_id存储评级,并用作关系表。
它的架构如下:
+----------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------------------+------+-----+---------+----------------+
| id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
| record_id| smallint(5) unsigned | NO | MUL | NULL | |
| user_id | smallint(5) unsigned | NO | MUL | NULL | |
| rating | int(1) | NO | | NULL | |
+----------+----------------------+------+-----+---------+----------------+
现在,在我的应用程序中,我有一个搜索功能,可以根据某个关键字获取记录。输出还应包括某条记录的平均评级和每条记录的评级总数。这可以通过以下查询来完成:
SELECT re.id, re.title, re.year, ROUND(avg(ra.rating)) as avg_rate,
COUNT(ra.record_id) as total_times_rated
FROM records re
LEFT JOIN ratings ra ON ra.record_id = re.id
GROUP BY re.id;
将给出以下输出:
+----+------------------------+------+----------+-------------------+
| id | title | year | avg_rate | total_times_rated |
+----+------------------------+------+----------+-------------------+
| 1 | Test Record 1 | 2008 | 3 | 4 |
| 2 | Test Record 2 | 2012 | 2 | 4 |
| 3 | Test Record 3 | 2003 | 3 | 4 |
| 4 | Test Record 4 | 2012 | 3 | 3 |
| 5 | Test Record 5 | 2003 | 2 | 3 |
| 6 | Test Record 6 | 2006 | 2 | 3 |
+----+------------------------+------+----------+-------------------+
问题:
现在,至少对我来说,这是棘手的部分。在我的应用程序中,您可以搜索是否已登录的记录,如果已登录,我还想在上述查询中包含用户自己的评级值。
我知道我可以运行条件来检查用户是否已登录,方法是读取会话值并根据该值执行相应的查询。我只是不知道如何将某个用户的个人评级值包含在上述查询中。
答案 0 :(得分:0)
您可以在列中添加SELECT
查询,在结果中添加用户评分:
SELECT re.id, re.title, re.year, ROUND(avg(ra.rating)) as avg_rate,
COUNT(ra.record_id) as total_times_rated,
(SELECT rating FROM ratings WHERE user_id = ? AND record_id = re.id) as user_rating
FROM records re
LEFT JOIN ratings ra ON ra.record_id = re.id
GROUP BY re.id;
我们可以从会话中获取user_id
并将其传递给此查询,以便在结果中生成user_rating
列。
假设用户可以多次评分记录,我使用了SUM
。如果没有,我们可以从查询中删除它。
<强>更新强>
如果您不希望GROUP BY
考虑该值,则可以将现有查询包装到另一个查询中并向其添加一列,例如:
SELECT a.id, a.title, a.year, a.avg_rate, a.total_times_rated,
(SELECT rating FROM ratings WHERE user_id = ? AND record_id = a.id) as user_rating
FROM (SELECT re.id as id, re.title as title, re.year as year, ROUND(avg(ra.rating)) as avg_rate,
COUNT(ra.record_id) as total_times_rated
FROM records re
LEFT JOIN ratings ra ON ra.record_id = re.id
GROUP BY re.id) a;