Как avg, а затем упорядочить данные в SQL, если они могут появиться в двух столбцах? - PullRequest
0 голосов
/ 03 февраля 2019

Итак, у меня есть таблица points с такими столбцами, как person1_id person2_id team_score, и вы можете видеть, что один человек может появиться в столбце person1_id или person2_id, потому что игрок может быть в нескольких командах, поэтому вопрос в том, как мнеполучить лучших n игроков с наивысшим average_score, который определяется средним значением всех team_score, в которых он | участвовал?как person_id average_score?

Ответы [ 4 ]

0 голосов
/ 03 февраля 2019

Я думаю, что ответ Тима - очень хороший ответ.Но, предполагая, что у вас есть таблица persons, вы можете сделать это без union all:

select p.person_id,
       (select avg(team_score)
        from points po
        where p.person_id in (po.person1_id, po.person2_id)
       ) as average_score
from persons p
order by average_score desc
limit 5;  -- or whatever

Более эффективное выражение, вероятно, наиболее эффективно:

select p.person_id,
       ( (select sum(team_score)
          from points po
          where p.person_id = po.person1_id
         ) +
         (select sum(team_score)
          from points po
          where p.person_id = po.person2_id
         )
       ) /
       nullif( (select count(*)
                from points po
                where p.person_id = po.person1_id
               ) +
               (select count(*)
                from points po
                where p.person_id = po.person2_id
               ), 0
             ) as average_score
from persons p
order by average_score desc
limit 5; 

Причина, по которой это более эффективно, заключается в том, что он может использовать индексы points(person1_id, team_score) и points(person2_id, team_score).

0 голосов
/ 03 февраля 2019

Вы можете решить вашу проблему с помощью функции coalesce, например:

SELECT    
  COALESCE(person1_id, person2_id) AS person_id,  
  AVG(team_score) as average_score 
FROM points  
GROUP BY COALESCE(person1_id, person2_id)
ORDER BY AVG(team_score)

В данном случае COALESCE(col1, col2) возвращает первый ненулевой столбец в списке.Вы можете сделать это с любым количеством столбцов.

Вот документы: https://www.sqlite.org/lang_corefunc.html#coalesce

0 голосов
/ 03 февраля 2019

Сначала вам нужно собрать всех отдельных игроков, а затем присоединить их к таблице points:

select 
  d.id person_id, 
  avg(p.team_score) avgscore 
from (
  select person1_id id from points
  union
  select person2_id id from points
) d inner join points p
on (p.person1_id = d.id) or (p.person2_id = d.id)
group by d.id
order by avgscore desc
limit 3

См. Демоверсию

0 голосов
/ 03 февраля 2019

Один подход использует объединение для создания единого логического столбца всех игроков и их очков:

SELECT
    person_id,
    AVG(team_score) AS average_score
FROM
(
    SELECT person1_id AS person_id, team_score FROM points
    UNION ALL
    SELECT person2_id, team_score FROM points
) t
GROUP BY
    person_id
ORDER BY
    AVG(team_score) DESC
LIMIT 10;   -- e.g. for the top 10, but you may replace 10 with any value you want
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...