Обновите столбец Sql другими значениями столбца в соответствии с условиями - PullRequest
0 голосов
/ 06 января 2019

Я пытаюсь обновить позицию для моего игрока в таблице. Эта таблица состоит из имени, идентификатора, точек и положения.

Значением по умолчанию для точек является 0, тогда позиция будет Unranked.

Если у двух пользователей одинаковые очки, то позиции будут одинаковыми.

Демонстрационный стол

id  | name | points | position
1   | a    | 0      | Unranked
2   | b    | 120    | 2
3   | c    | 130    | 3
4   | d    | 120    | 1

Требуемый результат должен быть

id  | name | points | position
1   | a    | 0      | Unranked
2   | b    | 120    | 2
3   | c    | 130    | 1
4   | d    | 120    | 2

Запрос будет похож на unranked update mytable set position = 'Unranked' Where points = 0 Как я буду использовать точки и запрос набора позиций?

Ответы [ 3 ]

0 голосов
/ 06 января 2019

Если ваша версия MySQl (MySQL 8.x) поддерживает оконную функцию, то возможно следующее:

SELECT name,
RANK() OVER (
    ORDER BY points DESC
) position
FROM mytable
where points != 0

Выбранные данные затем можно объединить для обновления, как в ответе Гордона Линоффа.

0 голосов
/ 06 января 2019

Нет необходимости хранить вычисляемый столбец position в таблице. Следующие работы для всех версий:

create table tab ( id int, name varchar(1), points int );
insert into tab values
(1,'a',  0),
(2,'b',120),
(3,'c',130),
(4,'d',120);
select t.id, t.name, t.points, 
       ( case when points = 0 then 'Unranked' else t.rnk end ) as position
  from
  (
    select t1.*,  
           @rnk := if(@pnt = points,@rnk,@rnk + 1) rnk,
           @pnt := points
      from tab t1 
     cross join (select @rnk := 0, @pnt := 0 ) t2
      order by points desc
   ) t
 order by t.id;

id  name  points  position
--  ----  ------  --------
1    a      0     Unranked
2    b     120       2
3    c     130       1
4    d     120       2

Если вы хотите сохранить столбец position в своей таблице, вы можете использовать следующий оператор update, связывая его через основной столбец id:

 update tab tt
    set position = ( select 
                     ( case when points = 0 then 'Unranked' else t.rnk end ) as position
                      from
                      (
                        select t1.*, 
                               @rnk := if(@pnt = points,@rnk,@rnk + 1) rnk,
                               @pnt := points
                          from tab t1 
                         cross join (select @rnk := 0, @pnt := 0 ) t2
                          order by points desc
                       ) t                    
                      where t.id = tt.id );

Rextester Demo

0 голосов
/ 06 января 2019

Это боль. Вы можете получить нужные результаты с помощью подзапроса, но это не совсем работает в предложении update. В select вы можете сделать:

select t.*,
       (select 1 + count(*)
        from t t2
        where t2.points > 0 and t2.points > t.points
       ) as rank
from t;

Теперь вы можете включить это в обновление:

update t join
       (select t.*,
               (select 1 + count(*)
                from t t2
                where t2.points > 0 and t2.points > t.points
               ) as new_position
        from t;
       ) tt
       on t.id = tt.id
    set t.position = tt.new_position
    where t.points > 0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...