2013-05-29 41 views
3

我想知道“TX”中的哪个团队没有玩过游戏。 (换句话说进出口寻找一个选择的记录,其中有在许多表中没有相关的记录。)获取没有相关记录的记录列表MySQL

这里是SQL:

(或者,如果你喜欢SQL小提琴是在这里:http://sqlfiddle.com/#!2/14106

CREATE TABLE `Team` (
    `ID` INT NOT NULL AUTO_INCREMENT , 
    `Name` VARCHAR(45) NULL , 
    `State` VARCHAR(45) NULL , 
    PRIMARY KEY (`ID`)); 

CREATE TABLE `Games` (
    `ID` INT NOT NULL AUTO_INCREMENT, 
    `Team_ID` INT NULL , 
    `Game_Day` DATE NULL , 
    PRIMARY KEY (`ID`)); 

    INSERT INTO `Team` (`Name`, `State`) VALUES ('Rams', 'TX'); 
    INSERT INTO `Team` (`Name`, `State`) VALUES ('Rockets', 'OK'); 
    INSERT INTO `Team` (`Name`, `State`) VALUES ('Bombers', 'TX'); 
    INSERT INTO `Team` (`Name`, `State`) VALUES ('Yellow Jackets', 'NV'); 
    INSERT INTO `Team` (`Name`, `State`) VALUES ('Wildcats', 'CT'); 
    INSERT INTO `Team` (`Name`, `State`) VALUES ('Miners', 'CO'); 
    INSERT INTO `Team` (`Name`, `State`) VALUES ('Bolts', 'TX'); 

    INSERT INTO `Games` (`Team_ID`, `Game_Day`) VALUES ('2', '2013-03-16'); 
    INSERT INTO `Games` (`Team_ID`, `Game_Day`) VALUES ('2', '2013-01-01'); 
    INSERT INTO `Games` (`Team_ID`, `Game_Day`) VALUES ('3', '2013-04-16'); 
    INSERT INTO `Games` (`Team_ID`, `Game_Day`) VALUES ('5', '2013-02-02'); 
    INSERT INTO `Games` (`Team_ID`, `Game_Day`) VALUES ('4', '2013-02-12'); 
    INSERT INTO `Games` (`Team_ID`, `Game_Day`) VALUES ('6', '2013-01-09'); 
    INSERT INTO `Games` (`Team_ID`, `Game_Day`) VALUES ('6', '2013-01-01'); 
    INSERT INTO `Games` (`Team_ID`, `Game_Day`) VALUES ('3', '2013-05-01'); 

我应该得到的结果是:

ID  Name  
1  Rams 
7  Bolts 

回答

3
SELECT `ID`, `Name` FROM `TEAM` 
    WHERE `ID` NOT IN (SELECT DISTINCT(`Team_ID`) from `Games`) 
    AND `State` = 'TX'; 

SqlFi狗here

+0

那真是太棒了...... – argentum47

1

希望这会有所帮助。

select t.ID,t.NAME 
FROM Team t 
WHERE t.state = 'TX' 
AND t.id NOT IN (SELECT g.TEAM_ID FROM Games g) 
4

使用外连接,只选择那些比赛

SELECT t.* 
FROM TEAM t 
LEFT JOIN GAMES g ON g.team_id = t.id 
WHERE t.state = 'TX' 
AND g.team_id is null -- return only rows that *don't* join 

这这SQL Fiddle

注意,使用连接将出执行副行排列 - 查询方法,特别是当数据集变大时。

+0

从性能的角度来看,这是一个更好的答案。 MySQL不能很好地满足子查询(现在使用的两个其他答案)。从长远来看,'LEFT OUTER JOIN'会表现更好。 –

+0

@CodyCaughlan绝对。子查询应尽可能避免,并且可以经常转换为正确的SQL功能 – Bohemian

+0

我同意,我的答案是不是一个非常有效的一个。这应该是被接受的答案。 – vidit

3

您也可以左连接到Games表并筛选没有对应的Games行的位置。这是通常比NOT IN快当表有很多行:

SELECT Team.ID, Team.Name 
FROM Team 
LEFT JOIN Games ON Team.ID = Games.Team_ID 
WHERE Team.State = 'TX' AND Games.ID IS NULL; 

如果没有一个Games排去与Teams排,Games.ID列将在结果无效,因此,如果您过滤器Games.ID IS NULL你会得到一个团队没有游戏的所有行。

有一个SQL小提琴here

+0

非常感谢所有! – JVMX

+0

你的答案得到了答案和更多upvotes,与我的答案相同,但在我的3分钟后发布。你必须分享你如何做到这一点! – Bohemian

+0

@波希米亚 - 抱歉,我甚至没有看到你的答案。我从Oracle的多年工作中了解到这一点。 –