Как найти максимальное значение val1, где val2 - максимальное значение?

СУБД Sybase

В моей таблице игроков есть 4 столбца:

  1. игрок
  2. счет
  3. post_dt
  4. add_dt

Если я хочу найти счет игрока, где post_dt - максимальное значение, а add_dt - максимальное значение этого post_dt и этого игрока, как мне это сделать? Мой запрос ниже занимает очень много времени и, вероятно, не очень эффективен.

select player, score from tb t1 
where post_dt in 
      (select max(add_dt) 
       from tb t2 
       where t1.player = t2.player and t2.post_dt in 
             (select max(post_dt) 
              from tb t2 
              where t1.player = t2.player))

Таблица

PLAYER    SCORE POST_DT      ADD_DT 

001         15  2017-02-01   2017-01-15
001         26  2017-02-01   2017-01-17  
001         31  2017-01-28   2017-01-10
002         4   2017-03-25   2017-02-25  
002         14  2017-03-25   2017-02-13
002         27  2017-03-25   2017-03-05
003         31  2017-01-02   2016-12-25
003         4   2017-01-03   2016-12-25

Ожидаемые результаты запроса:

01, 26, 2017-02-01, 2017-01-17
02, 27, 2017-03-25, 2017-03-05
03,  4, 2017-01-03, 2016-12-25

Какая у вас база данных?

D-Shih 03.08.2018 23:36

Можете ли вы немного его уточнить, желательно с некоторыми примерами данных. Трудно понять ваше требование.

Cetin Basoz 03.08.2018 23:36

какой продукт Sybase RDBMS (ASE? SQLAnywhere? IQ? Advantage?) и версия? в дополнение к комментарию Цетина прочтите Как создать минимальный, полный и проверяемый пример, затем вернитесь и обновите свой вопрос

markp-fuso 03.08.2018 23:37

Я обновил свой пост образцами данных.

Airbum88 04.08.2018 00:35
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
4
39
1

Ответы 1

Вы можете добиться этого, используя коррелированные подзапросы.

SELECT t1.player,
       t1.score
       FROM tb t1
       WHERE t1.post_dt = (SELECT max(t2.post_dt)
                                  FROM tb t2
                                  WHERE t2.player = t1.player)
             AND t1.add_dt = (SELECT max(t2.add_dt)
                                     FROM tb t2
                                     WHERE t2.player = t1.player
                                           AND t2.post_dt = t1.post_dt);

Или, если ваша СУБД поддерживает оконные функции, используйте оконную функцию rank().

SELECT x.player,
       x.score
       FROM (SELECT t.player,
                    t.score,
                    rank() OVER (PARTITION BY t.player
                                 ORDER BY t.post_dt DESC,
                                          t.add_dt DESC) r
                    FROM tb t) x
       WHERE x.r = 1;

Еще один вариант - внутреннее объединение подзапросов, которые создают максимумы по player или player и post_dt соответственно.

SELECT t1.player,
       t1.score
       FROM tb t1
            INNER JOIN (SELECT t2.player,
                               max(t2.post_dt) post_dt
                               FROM tb t2
                               GROUP BY t2.player) t3
                       ON t3.player = t1.player
                          AND t3.post_dt = t1.post_dt
            INNER JOIN (SELECT t3.player,
                               t3.post_dt,
                               max(t3.add_dt) add_dt
                               FROM tb t3
                               GROUP BY t3.player,
                                        t3.post_dt) t4
                       ON t4.player = t1.player
                          AND t4.post_dt = t1.post_dt
                          AND t4.add_dt = t1.add_dt;

Это здорово! Спасибо. Я использовал ваше второе решение.

Airbum88 09.08.2018 19:48

Другие вопросы по теме