Mysql 使用或条件内部连接两个表

Mysql 使用或条件内部连接两个表,mysql,sql,Mysql,Sql,我想执行以下类似的操作(不起作用): 我有一个表,competitor\u flags,它可以属于单个参赛者或一个团队(competitor\u id和team\u id),但不能同时属于两个团队。参赛者和参赛队各有一列,instance\u id,这就是我试图筛选的内容。因此,例如,我可能有一些属于实例id为13的参赛者的参赛者标志,还有一些属于实例id为13的团队的参赛者标志,我希望得到满足这些条件之一的参赛者标志 上面的查询不起作用,但是根据我想要的解释,有人能帮我解决这个问题吗?提前谢谢

我想执行以下类似的操作(不起作用):

我有一个表,
competitor\u flags
,它可以属于单个参赛者或一个团队(
competitor\u id
team\u id
),但不能同时属于两个团队。参赛者和参赛队各有一列,
instance\u id
,这就是我试图筛选的内容。因此,例如,我可能有一些属于实例id为13的参赛者的参赛者标志,还有一些属于实例id为13的团队的参赛者标志,我希望得到满足这些条件之一的参赛者标志


上面的查询不起作用,但是根据我想要的解释,有人能帮我解决这个问题吗?提前谢谢。

就这样离开吧。如果你知道它们中的一个总是空的,那么合并看起来会更好一些

SELECT COUNT(*) 
FROM contestant_flags cf
LEFT JOIN contestants c ON c.id = cf.contestant_id
LEFT JOIN teams t ON t.id = cf.team_id
WHERE
(cf.flag_id = 1) AND 
(cf.call_id IS NULL) AND 
(c.instance_id = 13 OR t.instance_id = 13)
SELECT COUNT(*) FROM contestant_flags
LEFT JOIN contestants ON contestants.id = contestant_flags.contestant_id
LEFT JOIN teams ON teams.id = contestant_flags.team_id
WHERE contestant_flags.flag_id = 1
AND contestant_flags.call_id IS NULL
AND COALESCE(contestants.instance_id, teams.instance_id) = 13;

这里有一种获得结果的方法(我想你正在寻找)

若要在
团队
参赛者
中有匹配行,但至少有一个匹配行时返回行,可以使用外部联接操作查找匹配行,然后在WHERE子句中使用谓词排除不匹配的行

如果
实例\u id
参赛者和/或
团队中不唯一,则此查询返回的计数可能大于
参赛者\u标志中匹配的行数

要仅计算
contesant_flags
中的行,而不计算由联接操作生成的任何“重复项”,可以将
count(*)
替换为
count(DISTINCT f.id)
。(我假设表
contesant_flags
有一个名为
id
的列,该列保证是非空且唯一的;将
id
替换为
参赛者_flags
中的任何其他非空唯一列(或表达式)

在更一般的情况下,为了只计算
参赛者标志
中的行,我们还可以使用EXISTS谓词

SELECT COUNT(*)
  FROM `contestant_flags` f
 WHERE f.flag_id = 1
   AND f.call_id IS NULL
   AND (  EXISTS 
           ( SELECT 1
               FROM `contestants` c
              WHERE c.id = f.contestant_id
                AND c.instance_id = 13
           ) 
       OR EXISTS
            ( SELECT 1
                FROM `teams` t
               WHERE t.id = f.team_id
                 AND t.instance_id = 13
            )
       )

您是否尝试过左连接而不是内部连接?请将示例数据和所需结果添加到您的问题中。为什么不让所有参赛者成为团队的成员。那么,如果某些团队只有一个成员,您是希望仅从参赛者标志表中获得行数,还是希望获得排列计数、连接操作返回的行数ons?@bksi很好,就是这样。我盯着它看了这么久,完全忽略了这个小事实。我希望你能给出一个答案,而不是一个评论,这样我就可以为你标记它。+1。只要我们保证
参赛者id
团队id
填充时将
为NULL
,这就行了。请注意,我们可以ld在
子句的
中添加谓词
和参赛者.instance_id=13
和团队.instance_id=13)
;有了适当的索引,这可能会稍微提高性能。
SELECT COUNT(*)
  FROM `contestant_flags` f
  LEFT
  JOIN `contestants` c
       ON c.id = f.contestant_id
       AND c.instance_id = 13
  LEFT 
  JOIN `teams` t
       ON t.id = f.team_id
       AND t.instance_id = 13
 WHERE f.flag_id = 1
   AND f.call_id IS NULL
   AND ( c.id IS NOT NULL OR t.id IS NOT NULL )
SELECT COUNT(*)
  FROM `contestant_flags` f
 WHERE f.flag_id = 1
   AND f.call_id IS NULL
   AND (  EXISTS 
           ( SELECT 1
               FROM `contestants` c
              WHERE c.id = f.contestant_id
                AND c.instance_id = 13
           ) 
       OR EXISTS
            ( SELECT 1
                FROM `teams` t
               WHERE t.id = f.team_id
                 AND t.instance_id = 13
            )
       )