mysql - 如何修复以下 SQL 查询?

标签 mysql

我创建了一个包含6个表(6个实体)的数据库,其中3个表分别称为“Sessions”、“Reviews”和“Persons”。其规范如下:

CREATE TABLE Sessions(
s_tutorID VARCHAR(6),
startTime DATETIME,
location VARCHAR(140) NOT NULL,
language VARCHAR(20) NOT NULL,
s_studentID VARCHAR(6),
paidOrNot BINARY(1) NOT NULL, 
reviewedOrNot BINARY(1), 
INDEX (startTime),
INDEX (language),
PRIMARY KEY (s_tutorID, startTime),
FOREIGN KEY (s_tutorID) REFERENCES TutorsAddedLanguage(tutorID) ON DELETE NO ACTION,
FOREIGN KEY (s_studentID) REFERENCES StudentsAddedPayment(studentID) ON DELETE NO ACTION,
CONSTRAINT s_tutorIDform CHECK (s_tutorID REGEXP '^[a-z]{2}\d{4}$' > 0),
CONSTRAINT s_studentIDform CHECK (s_studentID REGEXP '^[a-z]{2}\d{4}$' > 0));


CREATE TABLE Persons(
ID VARCHAR(6),
name VARCHAR(30) NOT NULL, 
photo VARCHAR(30) NOT NULL, 
department VARCHAR(30) NOT NULL, 
graduatingYear YEAR(4) NOT NULL,
gender BINARY(1) NOT NULL,
selfIntro VARCHAR(1000) NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT IDform CHECK (ID REGEXP '^[a-z]{2}\d{4}$' > 0));

CREATE TABLE Reviews(
r_tutorID VARCHAR(6),
r_sessionStartTime DATETIME,
r_studentID VARCHAR(6) NOT NULL,
r_sessionLanguage VARCHAR(20) NOT NULL,
-- score DECIMAL(2,1) NOT NULL,
score INT NOT NULL,
givenTime DATETIME NOT NULL,
comments VARCHAR(1000),
PRIMARY KEY (r_tutorID, r_sessionStartTime),
FOREIGN KEY (r_tutorID) REFERENCES Sessions(s_tutorID),-- ON UPDATE CASCADE,
FOREIGN KEY (r_studentID) REFERENCES Sessions(s_studentID),-- ON UPDATE CASCADE,
FOREIGN KEY (r_sessionStartTime) REFERENCES Sessions(startTime),-- ON UPDATE CASCADE,
FOREIGN KEY (r_sessionLanguage) REFERENCES Sessions(language),
CONSTRAINT r_studentIDform CHECK (r_studentID REGEXP '^[a-z]{2}\d{4}$' > 0),
CONSTRAINT r_tutorIDform CHECK (r_tutorID REGEXP '^[a-z]{2}\d{4}$' > 0),
CONSTRAINT scoreform CHECK (score <= 5 AND score >= 0));

然后,我在每个表中插入了一些假数据,确保每个数据条目之间的所有逻辑都是正确的。

现在,我想编写一个查询,选择 2016 年 1 月 3 日的所有 session , session 的语言为 ENG(英语),并且 Sessions.paidOrNot = '0'。输出应该是一个包含以下列的表:日期、开始时间、结束时间、位置、Tutor_name、Tutor_email。

我编写了以下 SQL 查询:

SELECT DATE_FORMAT(S.startTime,'%d %b %Y') AS date,      
DATE_FORMAT(S.startTime,'%h:%i %p') AS starttime,    
DATE_FORMAT(S.startTime + INTERVAL 30 MINUTE,'%h:%i %p') AS endtime, 
S.location, 
P.name AS Tutor_name, 
CONCAT(P.ID, '@gmail.com') AS Tutor_email 
FROM Sessions S, Persons P 
WHERE DATE_FORMAT(S.startTime,'%Y-%m-%d') = '2016-01-03' 
AND S.paidOrNot = '0' 
AND S.s_tutorID = P.ID 
AND S.language = 'ENG' 
ORDER BY S.startTime ASC;

输出表如下:

+-------------+-----------+----------+----------+------------------+---------------------+
| date        | starttime | endtime  | location | Tutor_name       | Tutor_email         |
+-------------+-----------+----------+----------+------------------+---------------------+
| 03 Jan 2016 | 09:00 AM  | 09:30 AM | AlexHall   | Mike Connolly    | mc9514@gmail.com |
| 03 Jan 2016 | 09:30 AM  | 10:00 AM | Winson     | Choko Cahill     | cc6624@gmail.com |
| 03 Jan 2016 | 10:00 AM  | 10:30 AM | Turner   | Mike Connolly    | mc9514@gmail.com |
| 03 Jan 2016 | 02:00 PM  | 02:30 PM | GrandHall   | Milenka Caterini | mc1894@gmail.com |
+-------------+-----------+----------+----------+------------------+---------------------+
4 rows in set (0.10 sec)

现在,我想在上面的查询结果表中添加另一列,名为“Average_Review_Score”的列,该列取Reviews表中该元组Tutor_name的Reviews.score的平均值,并且分数必须是scores在同一种语言(ENG)上。

例如,评论表如下所示:

mysql> select * from Reviews order by r_tutorID;
+------------+---------------------+--------------+-------------------+-------+---------------------+-----------------------------------------------------------------------------------------+
| r_tutorID | r_sessionStartTime  | r_studentID | r_sessionLanguage | score | givenTime           | comments                                                                                |
+------------+---------------------+--------------+-------------------+-------+---------------------+-----------------------------------------------------------------------------------------+
| ah0133     | 2015-10-02 15:00:00 | jc3323       | JAP               |     4 | 2015-10-02 18:55:33 | oh yeah!                                                                                |
| ah0133     | 2015-10-08 12:00:00 | mc9514       | JAP               |     4 | 2015-10-10 10:59:39 | NULL                                                                                    |
| cc6624     | 2015-09-13 20:00:00 | ah0133       | ENG               |     4 | 2015-10-01 06:38:52 | Choko did a good job helping me with English writing. But he was late for 10 minutes... |
| cc6624     | 2015-10-08 13:00:00 | ah0133       | ENG               |     0 | 2015-10-09 18:49:29 | The tutor did not show up at all                                                        |
| jc3323     | 2015-10-08 12:00:00 | as3699       | SPA               |     3 | 2015-10-08 12:32:41 | NULL                                                                                    |
| jc3323     | 2015-10-08 13:00:00 | es4937       | SPA               |     1 | 2015-10-09 16:01:17 | bad                                                                                     |
| mc1894     | 2015-10-01 12:00:00 | cc6624       | SPA               |     4 | 2015-10-01 12:35:08 | Good session, but I dont think its really helpful to improve my Spanish class grade!    |
| mc1894     | 2015-10-01 13:00:00 | as3699       | SPA               |     3 | 2015-10-02 12:00:00 | fair                                                                                    |
| mc9514     | 2015-10-02 11:30:00 | ep6229       | ENG               |     5 | 2015-11-04 14:22:01 | NULL                                                                                    |
| mc9514     | 2015-10-03 10:00:00 | as3699       | SPA               |     5 | 2015-10-03 11:13:31 | oh my god                                                                               |
| mc9514     | 2015-10-03 12:00:00 | cc6624       | LAT               |     3 | 2015-10-04 23:45:17 | enough                                                                                  |
| mc9514     | 2015-11-09 19:30:00 | pd0039       | ENG               |     2 | 2015-11-09 22:49:13 | not vey helpful                                                                         |
| pd0039     | 2015-10-09 12:00:00 | nm3384       | FRE               |     3 | 2015-10-11 03:14:36 | NULL                                                                                    |
+------------+---------------------+--------------+-------------------+-------+---------------------+-----------------------------------------------------------------------------------------+
13 rows in set (0.09 sec)

之前的 SQL 查询为我提供了 4 个 session ,如上面所列,我只是将其再次放在这里:

+-------------+-----------+----------+----------+------------------+---------------------+
| date        | starttime | endtime  | location | Tutor_name       | Tutor_email         |
+-------------+-----------+----------+----------+------------------+---------------------+
| 03 Jan 2016 | 09:00 AM  | 09:30 AM | AlexHall   | Mike Connolly    | mc9514@gmail.com |
| 03 Jan 2016 | 09:30 AM  | 10:00 AM | MidCafe     | Choko Cahill     | cc6624@gmail.com |
| 03 Jan 2016 | 10:00 AM  | 10:30 AM | Turner   | Mike Connolly    | mc9514@gmail.com |
| 03 Jan 2016 | 02:00 PM  | 02:30 PM | GrandHall   | Milenka Caterini | mc1894@gmail.com |
+-------------+-----------+----------+----------+------------------+---------------------+

现在,我想添加一列“Average_Review_Score”。例如,对于 Mike Connolly(ID:mc9514)教授的第一堂 ENG 类(class),“Average_Review_Score”的值应为 (5+2)/2 = 3.5,因为在如上所示的 Reviews 表中,该导师 Mike Connolly ( ID:mc9514)目前已收到4条评论,4条评论中,有2条是关于“ENG”的评论(Reviews.r_sessionLanguage):一条评论得分为5,另一条评论得分为2。同样我们想要找到所有其他两位导师的“Average_Review_Score”值:Choko Cahill (ID: cc6624) 和 Milenka Caterini (ID: mc1894)。

为了实现此目的,我编写了以下查询:

SELECT DATE_FORMAT(S.startTime,'%d %b %Y') AS date,      
DATE_FORMAT(S.startTime,'%h:%i %p') AS starttime,    
DATE_FORMAT(S.startTime + INTERVAL 30 MINUTE,'%h:%i %p') AS endtime, 
S.location, 
P.name AS Tutor_name, 
CONCAT(P.ID, '@gmail.com') AS Tutor_email, 
AVG(R.score) AS Average_Review_Score
FROM Sessions S, Persons P, Reviews R
WHERE DATE_FORMAT(S.startTime,'%Y-%m-%d') = '2016-01-03' 
AND S.paidOrNot = '0' 
AND S.s_tutorID = P.ID 
AND S.language = 'ENG' 
AND R.r_tutorID = S.s_tutorID 
AND R.r_sessionLanguage = S.language
ORDER BY S.startTime ASC;

但是,上面的这个查询只给了我一个 session :

+-------------+-----------+----------+----------+--------------+------------------+----------------------+
| date        | starttime | endtime  | location | Tutor_name   | Tutor_email      | Average_Review_Score |
+-------------+-----------+----------+----------+--------------+------------------+----------------------+
| 03 Jan 2016 | 09:30 AM  | 10:00 AM |  MidCafe    | Choko Cahill | cc6624@gmail.com |               3.0000 |
+-------------+-----------+----------+----------+--------------+------------------+----------------------+
1 row in set (0.09 sec)

那么我应该如何编写这个查询呢?这里出了什么问题?

最佳答案

最好使用“join”来连接表,然后使用“group by”来创建聚合。
选择...,
AVG(R.score) AS Average_Review_Score
来自 session S
在 S.s_tutorID = P.ID 上内部加入人员 P
左连接 R.r_tutorID = S.s_tutorID AND R.r_sessionLanguage = S.language 上的评论 R
哪里...
分组依据....
按 S.startTime ASC 排序;

关于mysql - 如何修复以下 SQL 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33684485/

相关文章:

php - 在同一 ID 中插入重复的 key 更新

php - Codeigniter 事件记录从 mysql 获取记录,其中 ID 等于数组中的记录

mysql - 如何从 zend 框架 View (phtml) 查询数据库?

php - 仅在选定的页面上放置 WordPress 插件

MySQL AUTO_INCRMENT 2 个表

mySQL 密码策略拒绝所有创建用户的尝试

Mysql select,如果输入参数相同则不返回任何行

MySQL - NOT IN (.... a gazillion items ... ),它会扩展吗?

mysql - 使用某些逻辑无法创建mysql事件

mysql - 为什么默认的MySql字符串匹配不区分大小写?