Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Group by в сложном запросе / 7 сообщений из 7, страница 1 из 1
26.03.2015, 10:41
    #38917407
Exact
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by в сложном запросе
У меня есть две таблицы. Игроки (упрощенный вариант): players(id, team_id) и игры games(id, date, home_team_id, away_team_id).

Мне нужно вывести id будущих игр для каждого игрока. В теории все понятно, нужно объединить две таблицы (через games.home_team_id = players.team_id or games.away_team_id = players.team_id). Затем сгруппировать по игроку, отфильтровать прошедшие игры и выбрать среди них минимальные даты). Но на практике не удается создать корректный запрос, который бы работал...

Код: sql
1.
2.
SELECT min(games.date) AS min_1, players.id AS u_id
FROM games join players on games.home_team_id=players.team_id or games.away_team_id=players.team_id where games.date > '2015-03-26 12:36:00+000' GROUP BY players.id ORDER BY players.id



Вот такой запрос работает, и на первый взгляд выдает корректные данные, но если я попытаюсь добавить в SELECT games.id, субд сообщит мне следующее: column "games.id" must appear in the GROUP BY clause or be used in an aggregate function
А если я пойду у нее на поводу и добавлю в GROUP BY games.id, то минимальная дата для каждой отдельно взятой игры будет, что логично - датой этой игры. Т.е. я получу не по одной игре для каждого игрока, а все его игры, что не выполняет поставленную задачу.

Как выйти из этой ситуации? Долго уже бьюсь, но решения найти не удается..
...
Рейтинг: 0 / 0
26.03.2015, 10:56
    #38917424
Exact
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by в сложном запросе
Exact, удалось найти на форуме решение, выводить в select агрегатную функцию, типа max(). Если данные одинаковые (а так и есть для одной и той же игры), то все будет ок. Но выглядит немного.. костыльно что ли
...
Рейтинг: 0 / 0
26.03.2015, 11:07
    #38917437
Exact
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by в сложном запросе
авторудалось найти на форуме решение, выводить в select агрегатную функцию, типа max(). Если данные одинаковые (а так и есть для одной и той же игры), то все будет ок.
Как оказалось, это не соответствует действительности. MIN (games.id) никак не связана с min (games.sheduled)
...
Рейтинг: 0 / 0
26.03.2015, 13:15
    #38917629
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by в сложном запросе
ExactУ меня есть две таблицы. Игроки (упрощенный вариант): players(id, team_id) и игры games(id, date, home_team_id, away_team_id).

Мне нужно вывести id будущих игр для каждого игрока. В теории все понятно, нужно объединить две таблицы (через games.home_team_id = players.team_id or games.away_team_id = players.team_id). Затем сгруппировать по игроку, отфильтровать прошедшие игры и выбрать среди них минимальные даты). Но на практике не удается создать корректный запрос, который бы работал...

Код: sql
1.
2.
SELECT min(games.date) AS min_1, players.id AS u_id
FROM games join players on games.home_team_id=players.team_id or games.away_team_id=players.team_id where games.date > '2015-03-26 12:36:00+000' GROUP BY players.id ORDER BY players.id



Вот такой запрос работает, и на первый взгляд выдает корректные данные, но если я попытаюсь добавить в SELECT games.id, субд сообщит мне следующее: column "games.id" must appear in the GROUP BY clause or be used in an aggregate function
А если я пойду у нее на поводу и добавлю в GROUP BY games.id, то минимальная дата для каждой отдельно взятой игры будет, что логично - датой этой игры. Т.е. я получу не по одной игре для каждого игрока, а все его игры, что не выполняет поставленную задачу.

Как выйти из этой ситуации? Долго уже бьюсь, но решения найти не удается..

читайте документацию по DISTINCT ON
это то что вам надо для решения этой задачи

--Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
26.03.2015, 14:35
    #38917749
Лопата
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by в сложном запросе
Maxim Boguk,
таки лучше послать сразу к LATERAL , хотя и ограничено >~ 9.3, но идеологически верно (до тех пор, пока оптимайзер ПЖ не научится таки прилично считать DISTINCT ON) . А иначе такие гробы из под школоты, освоившей DISTINCT ON лезут, мать моя -- женщина.
...
Рейтинг: 0 / 0
26.03.2015, 15:29
    #38917825
Ivan Durak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by в сложном запросе
какие еще дистинкт оны?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select * from
(
  SELECT games.date, players.id, games.id,  row_number() over (partition by players.id order by games.date) as SORT
  FROM games 
  inner join players on games.home_team_id=players.team_id or games.away_team_id=players.team_id 
  where games.date > '2015-03-26 12:36:00+000' 
) sub
where SORT = 1;
...
Рейтинг: 0 / 0
26.03.2015, 17:03
    #38917961
Лопата
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by в сложном запросе
Ivan Durak,
дурак ты, ваня

lateral вдоль индекса с LIMIT 1 дешевле окна . много дешевле. часто -- на порядки. а distinct on ... order by -- скорее всего сравним (в нынешней реализации оптимайзера) с окном.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Group by в сложном запросе / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]