Определите и отметьте время записи, используя SQL - PullRequest
0 голосов
/ 19 апреля 2020

Учитывая таблицу базы данных, которая содержит список времени гонки, я должен быть в состоянии определить, какие из выступлений быстрее, чем предыдущие финалы sh раз для этого спортсмена на определенном расстоянии c, например, это было их лучшее время на момент исполнения.

Кроме того, было бы лучше обновить это и сохранить как логическое значение в дополнительном столбце в состоянии покоя, а не пытаться вычислять при выполнении SELECT. База данных не заполняется в хронологическом порядке, поэтому не уверен, поможет ли TRIGGER. Я думал о запросе, который выполняется на всю таблицу после любых вставок / обновлений. Это может повлиять на производительность, поэтому может выполняться периодически, а не при каждом обновлении строки.

Это на сервере MySQL 5.6.47.

Пример таблицы

athleteId  date        distance   finishTime 
1          2020-01-04  5K         30:00
1          2020-01-11  5K         30:09
1          2020-01-18  5K         29:45
1          2020-01-25  5K         29:32
1          2020-02-01  5K         31:18
1          2020-02-02  10K        1:06:07
1          2020-02-08  5K         28:25
1          2020-02-23  10K        1:06:02
1          2020-02-23  10K        1:07:30

Ожидаемый результат

athleteId  date        distance   finishTime isPersonalBest
1          2020-01-04  5K         30:00      Y
1          2020-01-11  5K         30:09      N
1          2020-01-18  5K         29:45      Y
1          2020-01-25  5K         29:32      Y
1          2020-02-01  5K         31:18      N
1          2020-02-02  10K        1:06:07    Y
1          2020-02-08  5K         28:25      Y
1          2020-02-23  10K        1:06:02    Y
1          2020-02-23  10K        1:07:30    N

Данные являются лишь примером. Фактические конечные значения sh хранятся в секундах. Будет еще много спортсменов и различные дистанции. Если выступление является первым для этого спортсмена на таком расстоянии, оно будет классифицировано как личный рекорд.

Ответы [ 2 ]

1 голос
/ 19 апреля 2020

Если вы используете MysQL 8.0, вы можете использовать оконные функции:

select
    t.*,
    case when finishTime < min(finishTime) over(
        partition by athleteId, distance 
        order by date 
        rows between unbounded preceding and 1 preceding
    )
        then 'Y'
        else 'N'
    end isPersonalBest
from mytable t

В более ранних версиях одним из вариантов является коррелированный подзапрос:

select
    t.*,
    case when exists(
        select 1
        from mytable t1
        where 
            t1.athleteId = t.athleteId 
            and t1.distance = t.distance
            and t1.date < t.date
            and t1.finishTime <= t.finishTime
    )
        then 'N'
        else 'Y'
    end isPersonalBest
from mytable t

Я бы не стал Я не рекомендую хранить эту производную информацию. Вместо этого вы используете вышеуказанный запрос для создания представления.

1 голос
/ 19 апреля 2020

Вы можете использовать совокупный минимум в MySQL 8 +:

select t.*,
       (case when finishTime >=
                  min(finishTime) over (partition by athleteid, distance
                                        order by date
                                        rows between unbounded preceding and 1 preceding
                                       )
             then 'N' else 'Y'
        end) as isPersonalBest
from t;

Здесь - это скрипта db <>.

В более ранних версиях вы может использовать not exists:

select t.*,
       (case when not exists (select 1
                              from t t2
                              where t2.atheleteid = t.athleteid and
                                    t2.distance = t.distance and
                                    t2.date < t.date and
                                    t2.finishTime <= t.finishTime
                                  )
             then 'Y' else 'N'
        end) as isPersonalBest
from t;
...