MYSQL - 根据特定条件输出额外列

时间:2017-04-20 22:04:04

标签: mysql database relationship

起初,我想为提供如此薄弱的头衔而道歉;我无法以更好的方式描述它。

请考虑以下事项:我们有三个表,一个用于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 |
+----+------------------------+------+----------+-------------------+

问题:

现在,至少对我来说,这是棘手的部分。在我的应用程序中,您可以搜索是否已登录的记录,如果已登录,我还想在上述查询中包含用户自己的评级值。

我知道我可以运行条件来检查用户是否已登录,方法是读取会话值并根据该值执行相应的查询。我只是不知道如何将某个用户的个人评级值包含在上述查询中。

1 个答案:

答案 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;