2010-06-26 101 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