有能力发挥所有相同位置的回合球员

问题描述

我希望能够支持搜索玩家

让我们说“宝贝露丝”。我搜索那个玩家的名字。

我想返回一个查询,该查询显示了所有与贝斯·鲁特相同的位置以及其击球平均值和homerun_count。因此,贝贝·露丝(Babe Ruth)出战外野手和投手,所以我们希望球员同时出场。

玩家(id,姓名,batting_avg,homerun_count,rookie_season,retired_season)

位置(players_id,位置)

PLAYERS Table
id  | name       | batting_avg | homerun_count | rookie_season | retired_season
1   | Babe Ruth  |   .342      |    714        |     1914      |    1935
2   | Travis Wood|   .143      |      1        |      2010     |    2020
3   | Barry Bonds|   .298      |     762       |      1986     |    2007

Positions
players_id | position
    1      | Pitcher
    1      | Outfield
    2      | Pitcher
    2      | Outfield
    3      | Outfield

所以我们将Travis Wood返回为:

name         | id | batting_average | homerun_count
Travis Wood  | 2  |     .143        |      1

解决方法

这是一个关系划分问题。

我建议加入一个合并,以带走每个玩家的所有位置,并用exists条件过滤Babe Ruth所参加的位置。然后,您可以使用having子句来确保找到所有职位。

select pl.*
from players pl
inner join positions po on po.player_id = pl.id
where pl.name <> 'Babe Ruth' and exists (
    select 1
    from players pl1
    inner join positions po1 on po1.player_id = pl1.id
    where pl1.name = 'Babe Ruth' and po1.position = po.Position
)
group by pl.id
having count(*) = (
    select count(*) 
    from players pl1
    inner join positions po1 on po1.player_id = pl1.id
    where pl1.name = 'Babe Ruth'
)

Demo on DB Fiddle

id | name        | batting_avg | homerun_count | rookie_season | retired_season
-: | :---------- | ----------: | ------------: | ------------: | -------------:
 2 | Travis Wood |       0.143 |             1 |          2010 |           2020
,

此方法会汇总所有位置,因此您可以在它们上获得完全匹配:

with po as (
      select po.players_id,group_concat(position order by position) as positions
      from positions po 
      group by po.players_id
     ) 
select p.* 
from players p join
     po
     on po.players_id = p.id join
     (select po2.*
      from po po2 
      where po2.players_id = (select p2.id from players p2 where p2.name = 'Babe Ruth')
     ) p_br
     on b_br.positions = po.positions;

编辑:

如果您只想要Babe Rush的所有职位以及其他职位(可能):

with po as (
      select p.*,po.position
      from players p join
           positions po 
           on po.players_id = p.id
     ) 
select po.name,po.id,po.batting_average,po.homerun_count
from po pobr left join
     po
     on pobr.position = po.position
where pobr.name = 'Babe Ruth'
group by po.name,po.homerun_count
having count(*) = count(pobr.name);