仅当子表中的多行匹配时才从父表中选择行

时间:2016-02-17 19:41:59

标签: sql ms-access

我通过在数据库中保存信息来构建学习tic tac toe的代码。 我有两个表,Games(ID,Winner)Turns(ID,Turn,GameID,Place,Shape)。 我希望通过多个子信息找到父母 例如:

SELECT GameID FROM Turns WHERE
GameID IN (WHEN Turn = 1 THEN Place = 1) AND GameID IN (WHEN Turn = 2 THEN Place = 4);

这样的事情可能吗?
我正在使用ms-access。

  

Turm - 游戏转身
GameID - 游戏ID - 地点 - 放置在矩阵上   1 =右上角,9 =左下角
形状 - X或圆形

提前致谢

4 个答案:

答案 0 :(得分:3)

这个非常简单的查询可以在单次扫描中完成,并且不会要求您通过在字符串中存储多个值(颤抖)来违反第一范式

SELECT T.GameID
FROM Turns AS T
WHERE
   (T.Turn = 1 AND T.Place = 1)
   OR (T.Turn = 2 AND T.Place = 4)
GROUP BY T.GameID
HAVING Count(*) = 2;

没有必要加入以确定此信息,如其他答案所示。

请在您的数据库中使用正确的数据库设计原则,并且不要将多个值存储在一个字符串中,从而违反First Normal Form!

答案 1 :(得分:1)

您的问题的一般解决方案可以通过使用包含Turns表的两个实例之间的自联接的子查询来完成:

SELECT * FROM Games
WHERE GameID IN 
(
    SELECT Turns1.GameID
    FROM Turns AS Turns1 
    INNER JOIN Turns AS Turns2 
    ON Turns1.GameID = Turns2.GameID
    WHERE (
        (Turns1.Turn=1 AND Turns1.Place = 1) 
        AND 
        (Turns2.Turn=2 AND Turns2.Place = 4))
);

Turns之间的自我联接(别名Turns1和Turns2)是关键,因为如果您只是尝试同时应用这两组条件:

WHERE (
        (Turns.Turn=1 AND Turns.Place = 1) 
        AND 
        (Turns.Turn=2 AND Turns.Place = 4))

你永远不会得到任何行。这是因为在您的表中,单个行无法同时满足这两个条件。

我使用Access的经验是,要执行这样的复杂查询,您必须使用SQL视图并自己键入查询,而不是使用查询设计器。也许可以在Designer中完成,但我自己编写代码总是容易得多。

答案 2 :(得分:-2)

select GameID from Games g where exists (select * from turns t where 
t.gameid = g.gameId and ((turn =1 and place = 1) or (turn =2 and place =5)))

这将根据相应的标准选择至少一回合的所有比赛。

有关存在的更多信息: http://www.techonthenet.com/sql/exists.php

答案 3 :(得分:-2)

我通过添加一个将转弯保持为字符串示例的列来绕过这个问题:“154728”然后我搜索它。我认为这个解决方案对数据库的要求也不高