问题描述
这是我当前的查询。我今天发现了 INTERSECT,但是 MysqL 不支持它。谁能给我一些关于如何改进这个查询的建议?它给了我我正在寻找的结果,但速度很慢。
如果有帮助,我正在与运动队合作,并过滤统计数据。我过滤主队,然后是客队。我使用了 count(id) 方法,因为我只想返回在 both 查询中找到的夹具 ID,所以我认为 INTERSECT 会很完美。
select id,count(id) as count from (
select f.id,f.etc,etc
from fixtures f
inner join team_stats t on f.id = t.fixture_id and f.league_id = t.league_id and f.home_id = t.team_id
where f.status in ('FT','AET','PEN','FT_PEN') and
unix < 1619927451 and
played_overall between '11' and '60' and
scored_1h_home_avg between '0.7' and '6' and
o05_1h_goals_overall_per between '76' and '100' and
first_goal_total_avg between '0' and '35' and
scored_o05_1h_home_per >= 69
UNION ALL
select f.id,etc
from fixtures f
inner join team_stats t on f.id = t.fixture_id and f.league_id = t.league_id and f.away_id = t.team_id
where f.status in ('FT','FT_PEN') and
unix < 1619927451 and
played_overall between '11' and '60' and
conceded_1h_away_avg between '0.7' and '6' and
first_goal_total_avg between '0' and '35' and
o05_1h_goals_away_per between '77' and '100'
)
x group by id HAVING count(id) > 1
解决方法
您可以使用 exists
来获得您想要的:
select f.id
from fixtures f
inner join team_stats t on f.id = t.fixture_id and f.league_id = t.league_id and f.home_id = t.team_id
where f.status in ('FT','AET','PEN','FT_PEN') and
unix < 1619927451 and
played_overall between '11' and '60' and scored_1h_home_avg between '0.7' and '6' and o05_1h_goals_overall_per between '76' and '100' and first_goal_total_avg between '0' and '35' and scored_o05_1h_home_per >= 69
and exists(
select 1
from fixtures f2
inner join team_stats t on f2.id = t.fixture_id and f2.league_id = t.league_id and f2.away_id = t.team_id
where f2.status in ('FT','FT_PEN') and
unix < 1619927451 and
played_overall between '11' and '60' and
conceded_1h_away_avg between '0.7' and '6' and first_goal_total_avg between '0' and '35' and o05_1h_goals_away_per between '77' and '100'
and f1.id=f2.id)
另一种变体可以在没有 union all
的情况下组合两个查询。如果您的查询产生正确答案,那么这也应该这样做。
select id,count(id) as i_count
from fixtures f
inner join team_stats t on f.id = t.fixture_id and f.league_id = t.league_id
where f.status in ('FT','FT_PEN') and
unix < 1619927451 and
played_overall between '11' and '60'
and ((f.home_id = t.team_id and and scored_1h_home_avg between '0.7' and '6' o05_1h_goals_overall_per between '76' and '100' and first_goal_total_avg between '0' and '35' and scored_o05_1h_home_per >= 69)
or (f.away_id = t.team_id and conceded_1h_away_avg between '0.7' and '6' and first_goal_total_avg between '0' and '35' and o05_1h_goals_away_per between '77' and '100'))
group by id HAVING count(id) > 1
,
如果我的操作正确,两个查询中的情况相同:
select f.id,f.etc,etc
from fixtures f join
team_stats t
on f.id = t.fixture_id and f.league_id = t.league_id and f.away_id = t.team_id
where f.status in ('FT','FT_PEN') and
unix < 1619927451 and
played_overall between '11' and '60' and
conceded_1h_away_avg between '0.7' and '6' and
first_goal_total_avg between '0' and '35'
那么你需要这两个条件:
scored_o05_1h_home_per >= 69
o05_1h_goals_away_per between '77' and '100'
如果是这样,聚合可能是最简单的解决方案:
select f.id,'FT_PEN') and
unix < 1619927451 and
played_overall between '11' and '60' and
conceded_1h_away_avg between '0.7' and '6' and
first_goal_total_avg between '0' and '35'
group by f.id
having sum(scored_o05_1h_home_per >= 69) > 0 and
sum(o05_1h_goals_away_per between '77' and '100')
我还注意到您在看起来像数字的内容周围使用单引号。如果这些真的是数字,那么去掉单引号。不要混合类型。如果值以字符串形式存储,则比较以字符串形式而不是数字形式存储,并且可能不会按照您的预期进行。