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
)
)