不是那么简单的SQL查询

时间:2013-01-19 22:00:06

标签: mysql sql join

所以我完成了任务,有些人甚至在谷歌的帮助下仍未能解决。也许有人可以提出一些解决方案(是否必须使用JOINS?等等。)

这是数据库:

CREATE TABLE Foto (
    ID int PRIMARY KEY,
    FileName varchar(100),
    FileSize int,
    Created int
) DEFAULT CHARSET=utf8;

CREATE TABLE Users (
    LoginName varchar(10) PRIMARY KEY,
    Surname varchar(20),
    Name varchar(20),
    Created date,
    LastLoginDate date
) DEFAULT CHARSET=utf8;

CREATE TABLE Scoring (
    ID int,
    LoginName varchar(10),
    Score int,
    ScoreDate date,
    FOREIGN KEY (LoginName) REFERENCES Users(LoginName),
    FOREIGN KEY (ID) REFERENCES Foto(ID),
    PRIMARY KEY(ID, LoginName)
) DEFAULT CHARSET=utf8;

“Foto”(照片)和“用户”表格应该非常清楚。 “评分”表适用于对照片进行评分的用户。每个用户只能为每张照片评分一次。任务是:

  1. 编写将返回AVG得分高于9的所有照片的照片ID,FileName和AVG(得分)的查询,并创建可提高此查询性能的索引。

  2. 写入返回“LoginName”,“Name”,“Surname”的查询以及用户为其为特定用户评分的照片(例如,名称为“John”的用户)的AVG分数)。创建可以提高此查询性能的索引。

  3. 我正在使用MySQL 5.5.16,我对第一个查询的想法是这样的:

    SELECT F.ID, F.FileName, AVG(SC.Score)
    FROM Foto F, scoring SC
    WHERE F.ID = SC.ID
    AND AVG(SC.Score) > 9
    GROUP BY SC.ID;
    

    它返回“#1111 - 无效使用群组功能”,我从来没有真正喜欢聚合功能:D

    总的来说,我已经意识到我很喜欢SQL,我想培训更多地编写查询,但我在互联网上找到的大多数教程都有非常简单的例子,这些例子在解决这些问题方面没有多大帮助。也许你们中的一些人可以建议我一个资源,它可以有更复杂,更准备好的数据库和任务(如果我遇到困难,还有答案)来编写查询?

3 个答案:

答案 0 :(得分:4)

可能有用的一件事是学习使用显式JOIN语法(使用ON子句)而不是旧式隐式语法(使用WHERE子句`)。这有助于将来让事情更清楚。

您的错误是您需要使用HAVING子句来对聚合函数的结果进行子集化。您不能在WHERE子句中使用聚合函数。

所以,试试这个:

SELECT F.ID
     , F.FileName
     , AVG(SC.Score)
FROM   Foto F
JOIN   scoring SC
ON     F.ID = SC.ID
GROUP BY F.ID, F.FileName 
HAVING AVG(SC.Score) > 9
祝你好运!

编辑:了解任何数据库的最佳位置来自您正在使用的特定数据库的文档页面。在您的情况下,look here

答案 1 :(得分:4)

  

WHERE子句用于比较基表中的值,而   HAVING子句可用于过滤聚合的结果   函数在查询的结果集中。

     

HAVING子句已添加到SQL,因为WHERE关键字不能   与聚合函数一起使用。

(1) 您必须在查询中添加HAVING

SELECT F.ID, F.FileName, AVG(SC.Score)
FROM   Foto F INNER JOIN scoring S ON F.ID = S.ID
GROUP BY F.ID, F.FileName 
HAVING AVG(S.Score) > 9

(2)

SELECT U.LoginName, U.Name, U.Surname, AVG(S.Score)
FROM Scoring S INNER JOIN Users U ON S.LoginName = U.LoginName
GROUP BY S.LoginName

SQLFiddle Demo

希望答案能为您提供下一次考试的更好背景:)

答案 2 :(得分:1)

select中的所有内容都必须在GROUP BY或聚合函数中。

SELECT F.ID, F.FileName, AVG(SC.Score)
FROM Foto F
INNER JOIN scoring SC
ON F.ID = SC.ID
GROUP BY F.ID, F.FileName 
HAVING AVG(SC.Score) > 9

您要加入或搜索的任何列都可以从索引中受益。