Oracle SQL: Как создать таблицу точек соответствия крикету с такими сведениями, как счетчик выигрышей, счетчик проигрышей и т. Д.? - PullRequest
0 голосов
/ 09 декабря 2018

Я столкнулся с этим вопросом в интервью.Я должен был получить заработанные очки, счет выигрыша, счет проигрыша, счет ничьи в команде.Мой запрос дает мне правильный результат, но я ищу способ обойти запрос.Любая помощь?

Определенные условия, которые я рассмотрел в моем запросе:

1. If a team wins i am allocating 3 as match point and 2 if a team loses
2. If the match is a tie (when winner is null) i am awarding 1 point to each team.

DDL и DML:

create table match_t(team1 varchar(20),team2 varchar(20),Winner varchar(20));

insert into match_t values('India','Pakistan','India');
insert into match_t values('India','Srilanka','India');
insert into match_t values('Srilanka','Pakistan','Pakistan');
insert into match_t values('Srilanka','India','Srilanka');
insert into match_t values('Pakistan','Srilanka','Srilanka');
insert into match_t values('Pakistan','India','India');
insert into match_t values('India','Srilanka','India');
insert into match_t values('Pakistan','India',null);
insert into match_t values('Srilanka','Pakistan',null);
Commit;

Мой ответ на проблему:

with abc as(
select team1 as host,team2 as guest,case when team1=winner
then 1 else 0 end as host_w,
case when team2 = winner
then 1 else 0 end as guest_w  
 from match_t), bac as(
 select host,3 as m_point,1 as host_win,0 as guest_win,0 as match_d from abc where host_w > guest_w
 union all
 select guest,3 as m_point,0 as host_win,1 as guest_win,0 as match_d from abc where host_w < guest_w
union all
select guest,2 as m_point,0 as host_win,0 as guest_win,0 as match_d from abc where host_w > guest_w
 union all
 select host,2 as m_point,0 as host_win,0 as guest_win,0 as match_d from abc where host_w < guest_w
 union all
 select host,1 as m_point,0 as host_win,0 as guest_win, 1 as match_d from abc where host_w = guest_w
 union all
 select guest,1 as m_point,0 as host_win,0 as guest_win, 1 as match_d from abc where host_w = guest_w
 ),
 cad as(
 select host as team,sum(m_point) as match_p,sum(host_win+guest_win) as win_c,
sum(match_d)  as match_d_c 
 from bac group by host),
 dac as(select sum(lost_c) as lost_c,team from (select count(*) as lost_c,host as team from abc where host_w=0 and guest_w <> 0
 group by host
 union all
 select count(*) as lost_c,guest as team from abc where guest_w=0 and host_w <> 0
 group by guest) group by team)
  select a.team,a.match_p,a.win_c,b.lost_c,a.match_d_c,a.win_c+b.lost_c+a.match_d_c as no_match from cad a, dac b where a.team=b.team

Это дает мне правильный результат (см. Ниже).Но я ищу способ, как легко я могу получить это без написания такого длинного кода

enter image description here

Ответы [ 4 ]

0 голосов
/ 09 декабря 2018

Я бы сделал это, используя union all, но запрос был бы просто:

select team, sum(is_win) as num_wins, sum(is_loss) as num_losses, sum(is_tie) as num_ties
from ((select team1 as team,
               (case when winner = team1 then 1 else 0 end) as is_win,
               (case when winner = team2 then 1 else 0 end) as is_loss,
               (case when winner is null then 1 else 0 end) as is_tie
        from match_t
       ) union all
       (select team2,
               (case when winner = team2 then 1 else 0 end) as is_win,
               (case when winner = team1 then 1 else 0 end) as is_loss,
               (case when winner is null then 1 else 0 end) as is_tie
        from match_t
       )
      ) t
group by team;

Я немного удивлен тем, насколько сложны другие ответы.Идея довольно проста.Для каждой команды в матче вам нужны флаги, указывающие, была ли игра победой, поражением или ничьей.Затем вы хотите объединить эти флаги по всем командам.

0 голосов
/ 09 декабря 2018

Один способ решить эту проблему, используя union all, чтобы получить команду и соответствующий результат в столбце, а затем использовать group by, чтобы получить все выигрыши, проигрыши, связи и общее количество очков.

select team
,count(*) as num_matches
,sum(points) as total_points
,sum(case when result='Win' then 1 else 0 end) as num_wins
,sum(case when result='Lose' then 1 else 0 end) as num_losses
,sum(case when result='Tie' then 1 else 0 end) as num_ties
from (select winner as team,3 as points,'Win' as result
      from match_t
      where winner is not null
      union all 
      select case when winner = least(team1,team2) then greatest(team1,team2) else least(team1,team2) end,2,'Lose'
      from match_t
      where winner is not null
      union all
      select team1,1,'Tie'
      from match_t
      where winner is null
      union all
      select team2,1,'Tie'
      from match_t
      where winner is null
     ) t
group by team
0 голосов
/ 09 декабря 2018

Вы можете использовать unpivot, чтобы получить желаемые результаты.

with data
  as (select row_number() over(order by 1) as rnk
            ,t.team1
            ,t.team2
            ,t.winner
            ,case when t.winner is not null then 
                  case when t.team1 <> t.winner then t.team1
                       else t.team2
                  end
             end as loser
            ,case when t.winner is null then t.team1 end tie1
            ,case when t.winner is null then t.team2 end tie2
       from match_t t
       )
  ,folded_data
   as (select *
         from data
       unpivot(val for x in (winner
                            ,loser
                            ,tie1
                            ,tie2
                             )
               )t
      )
 select val
        ,sum(case when x='WINNER' then 3
                  when x='LOSER'  then 2
                  when x in ('TIE1','TIE2') then 1
              end) as tot_points
        ,count(rnk) as match_played   
        ,count(case when x='WINNER' then 1 end) as win_count
        ,count(case when x='LOSER' then 1 end) as loser_count
        ,count(case when x in('TIE1','TIE2') then 1 end) as tie_count
   from folded_data
 group by val   

Вот ссылка dbfiddle

https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=0aabf7d1f19ecd010f53903b56427959

0 голосов
/ 09 декабря 2018

Вы можете попытаться использовать функцию с условными усугублениями один раз UNION ALL, чтобы очистить код.

Настройка схемы Oracle 11g R2 :

create table match_t(team1 varchar(20),team2 varchar(20),Winner varchar(20));

insert into match_t values('India','Pakistan','India');
insert into match_t values('India','Srilanka','India');
insert into match_t values('Srilanka','Pakistan','Pakistan');
insert into match_t values('Srilanka','India','Srilanka');
insert into match_t values('Pakistan','Srilanka','Srilanka');
insert into match_t values('Pakistan','India','India');
insert into match_t values('India','Srilanka','India');
insert into match_t values('Pakistan','India',null);
insert into match_t values('Srilanka','Pakistan',null);

Запрос 1 :

SELECT 'Srilanka' Team,
        SUM(CASE WHEN Winner = 'Srilanka' AND (team1 = 'Srilanka' or team2='Srilanka') then 3 
                 WHEN Winner IS NULL  AND (team1 = 'Srilanka' or team2='Srilanka') THEN 1 
                 WHEN team1 = 'Srilanka' or team2='Srilanka' THEN 2 END
           )MATCH_P,
        COUNT(CASE WHEN  Winner = 'Srilanka'  THEN 1 END) WIN_C,
        COUNT(CASE WHEN  Winner <> 'Srilanka'AND (team1 = 'Srilanka' or team2='Srilanka') THEN 1 END) LOST_C,
        COUNT(CASE WHEN  Winner IS NULL AND (team1 = 'Srilanka' or team2='Srilanka') THEN 1 END) MATCH_D_C,
        COUNT(CASE WHEN  (team1 = 'Srilanka' or team2='Srilanka') THEN 1 END) NO_MATCH
FROM match_t
UNION ALL
SELECT 'Pakistan' Team,
        SUM(CASE WHEN Winner = 'Pakistan' AND (team1 = 'Pakistan' or team2='Pakistan') then 3 
                 WHEN Winner IS NULL  AND (team1 = 'Pakistan' or team2='Pakistan') THEN 1 
                 WHEN team1 = 'Pakistan' or team2='Pakistan' THEN 2 END
           )MATCH_P,
        COUNT(CASE WHEN  Winner = 'Pakistan'  THEN 1 END) WIN_C,
        COUNT(CASE WHEN  Winner <> 'Pakistan'AND (team1 = 'Pakistan' or team2='Pakistan') THEN 1 END) LOST_C,
        COUNT(CASE WHEN  Winner IS NULL AND (team1 = 'Pakistan' or team2='Pakistan') THEN 1 END) MATCH_D_C,
        COUNT(CASE WHEN  (team1 = 'Pakistan' or team2='Pakistan') THEN 1 END) NO_MATCH
FROM match_t
UNION ALL
SELECT 'India' Team,
        SUM(CASE WHEN Winner = 'India' AND (team1 = 'India' or team2='India') then 3 
                 WHEN Winner IS NULL  AND (team1 = 'India' or team2='India') THEN 1 
                 WHEN team1 = 'India' or team2='India' THEN 2 END
           )MATCH_P,
        COUNT(CASE WHEN  Winner = 'India'  THEN 1 END) WIN_C,
        COUNT(CASE WHEN  Winner <> 'India'AND (team1 = 'India' or team2='India') THEN 1 END) LOST_C,
        COUNT(CASE WHEN  Winner IS NULL AND (team1 = 'India' or team2='India') THEN 1 END) MATCH_D_C,
        COUNT(CASE WHEN  (team1 = 'India' or team2='India') THEN 1 END) NO_MATCH
FROM match_t

Результаты :

|     TEAM | MATCH_P | WIN_C | LOST_C | MATCH_D_C | NO_MATCH |
|----------|---------|-------|--------|-----------|----------|
| Srilanka |      13 |     2 |      3 |         1 |        6 |
| Pakistan |      11 |     1 |      3 |         2 |        6 |
|    India |      15 |     4 |      1 |         1 |        6 |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...