несколько первых n запросов

Мне трудно получить следующий запрос:

Допустим, у меня есть стол с большим количеством команд, и в каждой команде по 15 игроков (один ко многим для таблицы игроков).

Эти игроки упорядочиваются внутри команды в столбце «Порядок» от 0 до 14 и имеют два атрибута:

  • Набранные очки (целое число)
  • wasSick (логическое значение или целое число со значениями 0 для false или 1 для true)

Мне нужен запрос, который возвращает строку для каждой команды, где первый столбец — это идентификатор команды (первичный ключ), а второй — сумма очков, набранных первыми 11 игроками из каждая команда, которая не заболела, используя порядок, указанный в столбце Порядок.

Если болело более 3-х игроков, команда использовала всех оставшихся.

Это противоречит базе данных Oracle. Я пытался использовать ROWNUM, но мне нужен аналогичный rownum, который сбрасывается для каждой агрегации. Запрос может содержать подзапросы или использовать предложение WITH.

Спасибо!

PD: Если вы догадались, это футбольные команды.

ИЗМЕНИТЬ

Атрибут, используемый для определения порядка игроков в команде, — это столбец порядка. Назовем его столбцом «Позиция», и он имеет целое число от 0 до 14. Итак, если в команде болеют игроки 2 и 4, мне нужна сумма очков, набранных игроками 0,1,3,5,6, 7,8,9,10,11 и 12.

Моя попытка была примерно такой:

SELECT t.id, sum(p.points) FROM team t, points p WHERE p.t_id = t.id AND p.wasSick = 0 AND ROWNUM < 12 GROUP BY p.t_id

Что здесь не так, так это то, что мне не хватает ORDER BY p.position и что ROWNUM не сбрасывается между командами.


person Luciano    schedule 04.01.2011    source источник
comment
Когда вы говорите об очках, набранных первыми 11 игроками каждой команды, есть ли какой-либо атрибут/столбец, который можно использовать для их упорядочения?   -  person Chandu    schedule 05.01.2011
comment
Вы можете опубликовать свою попытку (ы)?   -  person Mitch Wheat    schedule 05.01.2011


Ответы (2)


Поскольку нет ссылки на поле, которое можно использовать для идентификации первых 11 игроков (если ни один из игроков в команде не болен), я использовал rowid, чтобы упорядочить их. Если вы можете обновить вопрос с таким полем, я могу изменить запрос. До тех пор:

SELECT team_id,
       SUM(points)
  FROM (
        SELECT t.team_id, 
               p.points
               ROW_NUMBER() OVER(PARTITION BY team_id ORDER BY player_id, p.rowid) rn
          FROM teams t, players p
              WHERE t.team_id = p.team_id
                AND p.wasSick = 0
        )
 WHERE rn < 12
 GROUP BY team_id
person Chandu    schedule 04.01.2011
comment
Я нашел ROW_NUMBER при поиске решения, но не понял его. Теперь на вашем примере понятнее. Я попробую этот подход, когда вернусь на работу завтра. - person Luciano; 05.01.2011
comment
Да, row_number был тем, что я искал. - person Luciano; 06.01.2011

Как насчет этого:

select teamid, 
       sum(pointscored)
  from (select teamid, 
               pointscored, 
               row_number() over (partition by teamid order by orderid) rn
          from (select 1 teamid, 1 playerid, 0 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 2 playerid, 1 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 3 playerid, 2 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 4 playerid, 3 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 5 playerid, 4 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 6 playerid, 5 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 7 playerid, 6 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 8 playerid, 7 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 9 playerid, 8 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 10 playerid, 9 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 11 playerid, 10 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 12 playerid, 11 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 13 playerid, 12 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 14 playerid, 13 orderid, 1 pointscored, 0 wassick from dual union all
                select 1 teamid, 15 playerid, 14 orderid, 1 pointscored, 0 wassick from dual union all
                select 2 teamid, 1 playerid, 0 orderid, 1 pointscored, 1 wassick from dual union all
                select 2 teamid, 2 playerid, 1 orderid, 1 pointscored, 1 wassick from dual union all
                select 2 teamid, 3 playerid, 2 orderid, 1 pointscored, 1 wassick from dual union all
                select 2 teamid, 4 playerid, 3 orderid, 1 pointscored, 1 wassick from dual union all
                select 2 teamid, 5 playerid, 4 orderid, 1 pointscored, 0 wassick from dual union all
                select 2 teamid, 6 playerid, 5 orderid, 1 pointscored, 0 wassick from dual union all
                select 2 teamid, 7 playerid, 6 orderid, 1 pointscored, 0 wassick from dual union all
                select 2 teamid, 8 playerid, 7 orderid, 1 pointscored, 0 wassick from dual union all
                select 2 teamid, 9 playerid, 8 orderid, 1 pointscored, 0 wassick from dual union all
                select 2 teamid, 10 playerid, 9 orderid, 1 pointscored, 0 wassick from dual union all
                select 2 teamid, 11 playerid, 10 orderid, 1 pointscored, 0 wassick from dual union all
                select 2 teamid, 12 playerid, 11 orderid, 1 pointscored, 0 wassick from dual union all
                select 2 teamid, 13 playerid, 12 orderid, 1 pointscored, 0 wassick from dual union all
                select 2 teamid, 14 playerid, 13 orderid, 1 pointscored, 0 wassick from dual union all
                select 2 teamid, 15 playerid, 14 orderid, 1 pointscored, 0 wassick from dual
               ) teams
         where wassick = 0
       )
 where rn <= 11
group by teamid;

который возвращает:

    TEAMID SUM(POINTSCORED)
---------- ----------------
         1               11
         2               11

2 rows selected.
person Doug Porter    schedule 04.01.2011
comment
почти то же самое, что и @Cybernate, но упорядочено по идентификатору заказа в пункте окна. Великие умы думают одинаково. - person Doug Porter; 05.01.2011
comment
Хорошо, вы поняли, в чем моя проблема, теперь мне нужно понять ваше решение! Запрос в запросе внутри запроса звучит глубоко, не говоря уже о том, что нужный мне запрос уже входит в более крупный запрос. - person Luciano; 05.01.2011
comment
@Luciano: вложенных запросов не следует бояться. Большая часть моего запроса - это образцы данных. Что он делает: 1) Исключает больных людей 2) Использует аналитическую функцию (row_number) для каждой команды, чтобы присвоить возрастающий номер каждой строке для этой команды, упорядоченной по orderid 3) Исключая все, кроме чисел 1-11, из списка результаты нашей аналитической функции 4) Группировка по командам для суммирования баллов. - person Doug Porter; 05.01.2011