2010-06-26 87 views
2

这是我的设置:MySQL的多表查询的每一行

  • 表 “文件”:ID(PK),文件名,USER_ID,日期,文件大小
  • 表 “算账”:ID( PK),file_id,user_id,得分

表“文件”包含文件列表的详细信息;表“分数”记录每个文件得分1-5分。我需要从“文件”表中获取条目,并且在每一行中我都需要文件的所有信息以及平均分数。我可以为当前的file_id做另一个查询,而我正在遍历行,但显然这并不是非常优化。我尝试了下面的东西,但没有成功。

SELECT files.*, (SUM(scores.score)/(COUNT(scores.score))) AS total FROM files INNER JOIN scores ON files.id=scores.file_id;

请点我在正确的方向 - 谢谢!

+0

为什么你在两个表中都有'user_id'? – 2010-06-26 05:39:41

+0

在“文件”中,它表示这个文件属于谁,在“分数”中表示谁对这个文件进行了评分。 – Alex 2010-06-26 05:43:00

+0

然后考虑给出字段相关的名称(例如'owner'和'rater')。 – 2010-06-26 05:44:16

回答

4

你可能想尝试以下操作:

SELECT f.id, f.filename, f.user_id, f.date, f.filesize, 
     (
      SELECT AVG(s.score) 
      FROM scores s 
      WHERE s.file_id = f.id 
     ) average_score 
FROM files f; 

注意,您可以使用AVG()聚合函数。没有必要将SUM()除以COUNT()

测试用例:

CREATE TABLE files (id int, filename varchar(10)); 
CREATE TABLE scores (id int, file_id int, score int); 

INSERT INTO files VALUES (1, 'f1.txt'); 
INSERT INTO files VALUES (2, 'f2.txt'); 
INSERT INTO files VALUES (3, 'f3.txt'); 
INSERT INTO files VALUES (4, 'f4.txt'); 

INSERT INTO scores VALUES (1, 1, 10); 
INSERT INTO scores VALUES (2, 1, 15); 
INSERT INTO scores VALUES (3, 1, 20); 
INSERT INTO scores VALUES (4, 2, 5); 
INSERT INTO scores VALUES (5, 2, 10); 
INSERT INTO scores VALUES (6, 3, 20); 
INSERT INTO scores VALUES (7, 3, 15); 
INSERT INTO scores VALUES (8, 3, 15); 
INSERT INTO scores VALUES (9, 4, 12); 

结果:

SELECT f.id, f.filename, 
     (
      SELECT AVG(s.score) 
      FROM scores s 
      WHERE s.file_id = f.id 
     ) average_score 
FROM files f; 

+------+----------+---------------+ 
| id | filename | average_score | 
+------+----------+---------------+ 
| 1 | f1.txt |  15.0000 | 
| 2 | f2.txt |  7.5000 | 
| 3 | f3.txt |  16.6667 | 
| 4 | f4.txt |  12.0000 | 
+------+----------+---------------+ 
4 rows in set (0.06 sec) 

注意@Ignacio's solution产生相同的结果,因此,是另一种选择。

+0

我的SQL知识是sub par :(什么是“分数s”和“文件f”? – Alex 2010-06-26 05:58:07

+0

得到它的工作,谢谢你们! – Alex 2010-06-26 06:27:04

+0

@Alex:'f'中的'f'只是一个别名。只是写'f.id,f.filename'而不是'files.id,files.filename'等的简写。这同样适用于'scores s'。 – 2010-06-26 06:33:32

3

如果没有聚合,聚合函数通常不会有用。

SELECT f.*, AVG(s.score) AS total 
FROM files AS f 
INNER JOIN scores AS s 
    ON f.id=s.file_id 
GROUP BY f.id