2012-12-02 85 views
0

这是连接这4个表的最有效方式吗?也有可能只选择每个表的一些行?我尝试将*更改为列的名称,但只允许来自studentlist的列。SQL查询;内连接4个表

SELECT c.classID, c.instrument, c.grade, u.ID, u.firstname, u.lastname, u.lastsongplayed, u.title 
FROM studentlist s 
INNER JOIN classlist c ON s.listID = c.classID 
INNER JOIN (

SELECT * 
FROM users u 
INNER JOIN library l ON u.lastsongplayed = l.fileID 
) 

u ON s.studentID = u.ID 
    WHERE teacherID =3 
    ORDER BY classID 
    LIMIT 0 , 30 

数据库结构:

CREATE TABLE IF NOT EXISTS `classlist` (
    `classID` int(11) NOT NULL AUTO_INCREMENT, 
    `teacherID` int(11) NOT NULL, 
    `instrument` text, 
    `grade` int(11) DEFAULT NULL, 
    PRIMARY KEY (`classID`), 
    KEY `teacherID_2` (`teacherID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=27 ; 


CREATE TABLE IF NOT EXISTS `studentlist` (
    `listID` int(11) NOT NULL, 
    `studentID` int(11) NOT NULL, 
    KEY `teacherID` (`studentID`), 
    KEY `studentID` (`studentID`), 
    KEY `listID` (`listID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 


CREATE TABLE IF NOT EXISTS `users` (
    `ID` int(11) NOT NULL AUTO_INCREMENT, 
    `email` varchar(60) NOT NULL, 
    `password` varchar(60) NOT NULL, 
    `firstname` text NOT NULL, 
    `lastname` text NOT NULL, 
    `sessionID` varchar(60) DEFAULT NULL, 
    `lastlogin` time DEFAULT NULL, 
    `registerdate` date NOT NULL, 
    `isteacher` tinyint(1) DEFAULT NULL, 
    `isstudent` tinyint(1) DEFAULT NULL, 
    `iscomposer` tinyint(1) DEFAULT NULL, 
    `lastsongplayed` int(11) NOT NULL, 
    PRIMARY KEY (`ID`), 
    UNIQUE KEY `ID` (`ID`), 
    UNIQUE KEY `email` (`email`,`sessionID`), 
    KEY `ID_2` (`ID`), 
    KEY `ID_3` (`ID`), 
    KEY `lastsongplayed` (`lastsongplayed`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=63 ; 

CREATE TABLE IF NOT EXISTS `library` (
    `fileID` int(11) NOT NULL AUTO_INCREMENT, 
    `userID` int(11) NOT NULL, 
    `uploaddate` datetime NOT NULL, 
    `title` varchar(60) NOT NULL, 
    `OrigComposer` varchar(60) NOT NULL, 
    `composer` varchar(60) NOT NULL, 
    `genre` varchar(60) DEFAULT NULL, 
    `year` year(4) DEFAULT NULL, 
    `arrangement` varchar(60) DEFAULT NULL, 
    PRIMARY KEY (`fileID`), 
    KEY `userID` (`userID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=77 ; 

回答

1

这是连接这些表3的最有效的方法是什么?

你的JOIN看起来是正确的,你加入你的钥匙。所以这应该是有效的。不过,我鼓励你用EXPLAIN分析你的查询来确定额外的优化。

是否有可能只选择每个表的一些行?

是的。将*更改为您想要的每个表中的列。我鼓励你明确地将它们作为前缀表的前缀。根据您选择的列,这也可以使您的查询更高性能。

SELECT studentlist.studentID, users.email FROM ... 
+0

thx是否可以将结果组合在一起?我想为每个班级制作一个新的分区,然后向该班的同学展示。 – Thomas

+0

我已经添加了另一个内连接;它仍然有效吗? – Thomas

+0

*行*,而不是列。通过使用派生表或通过[向JOIN子句添加条件](http://dev.mysql.com/doc/refman/5.6/en/join.html)选择每个表的* some *行。 “与ON一起使用的conditional_expr是可以在WHERE子句中使用的任何形式的条件表达式。通常,您应该使用ON子句来指定如何连接表的条件,以及WHERE子句来限制所需的行结果集“。在决定保留哪些方法之前,请阅读这些方法的EXPLAIN计划(派生表与条件中的JOIN和WHERE)。 –