我有3张桌子:冠军,角色,champs_to_roles
champs_to_roles表看起来像这样:
|ID_champ|ID_role|
----------------
| 2| 2|
| 4| 5|
| 5| 3|
| 3| 2|
| 1| 1|
| 1| 2|
我正在尝试选择ID_champ WHERE ID_role = 1 AND ID_role = 2.
此时我有以下代码:
SELECT DISTINCT `c`.`name`
FROM `champions` AS c,
(
SELECT `ID_champ`
FROM `champs_to_roles`
WHERE `ID_role` IN(1,2)
) AS r
WHERE `r`.`ID_champ` = `c`.`ID`
但是,这会返回ID_champ,ID_role = 1或Id_role = 2或两者都
我如何获取我需要的东西?
非常感谢:)
答案 0 :(得分:4)
对关联表使用两个内部联接 - 每个角色类型一个:
SELECT c.name
FROM champions c
JOIN champs_to_roles ctr1 ON ctr1.ID_champ = c.id AND ctr1.ID_role = 1
JOIN champs_to_roles ctr2 ON ctr2.ID_champ = c.id AND ctr2.ID_role = 2
通过使用内部连接, champs_to_roles
中的行必须存在才能返回冠军。
DISTINCT关键字是免费的,因为你不需要它(除非你的关联表中有重复的条目,这似乎不太可能,如果可能的话,设计也很糟糕)
答案 1 :(得分:0)
我可能会选择Bohemian的解决方案,但为了完整性,还可以使用计数并检查从子选择返回的角色数
SELECT c.name
FROM champions AS c
INNER JOIN
(
SELECT ID_champ, COUNT(DISTINCT ID_role) AS NumRole
FROM champs_to_roles
WHERE ID_role IN(1,2)
GROUP BY ID_champ
) AS r
ON r.ID_champ = c.ID AND NumRole = 2
(这也可以在没有subselect的情况下完成,但如果你没有返回需要分组的列等,那么它的可读性就会降低)
答案 2 :(得分:0)
您可以尝试以下方式:
Select
c.name
from
champions c
where
exists( select
1
from
champs_to_roles ctr1
where
ctr1.ID_champ = c.ID
and exists( select
1
from
champs_to_roles ctr2
where
ctr2.ID_champ = ctr1.ID_champ
and ctr2.ID_role <> ctr1.ID_role))
答案 3 :(得分:0)
试试这个,
SELECT DISTINCT c.name
FROM champions AS c,
(
SELECT c1.ID_champ
FROM champs_to_roles c1, champs_to_roles c2
WHERE c1.ID_role=1 and c2.ID_role=2
AND c1.ID_champ=c2.ID_champ
) AS r
WHERE r.ID_champ = c.ID