MySQL порядок по отдельным пунктам - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть таблица владений предметами, которая выглядит примерно так:

item_possession
===============
id      product_id      status
1       50 (weapon)     available
2       50 (weapon)     unavailable
3       10 (shield)     unavailable
4       10 (shield)     unavailable
5       50 (weapon)     available
6       20 (helmet)     available
7       20 (helmet)     available
8       50 (weapon)     available
9       50 (weapon)     available
10      30 (thunder)    unavailable
11      20 (helmet)     available

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

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

Примерно так:

item_possession
===============
id      product_id      status
1       50 (weapon)     available
3       10 (shield)     unavailable
6       20 (helmet)     available
8       30 (thunder)    unavailable
2       50 (weapon)     unavailable
4       10 (shield)     unavailable
5       50 (weapon)     available
7       20 (helmet)     available
8       50 (weapon)     available
9       50 (weapon)     available
10      30 (thunder)    unavailable
11      20 (helmet)     available

Ответы [ 3 ]

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

или, старая школа ...

SELECT x.*
  FROM item_possession x 
  JOIN item_possession y 
    ON y.product_id = x.product_id 
   AND y.id <= x.id 
 GROUP 
    BY x.id 
 ORDER 
    BY COUNT(*)
     , id;

РЕДАКТИРОВАТЬ: На самом деле, вы, кажется, хотите это ...

SELECT x.*
  FROM item_possession x 
  LEFT 
  JOIN 
     ( SELECT MIN(id) id FROM item_possession GROUP BY product_id ) y
    ON y.id = x.id
  ORDER 
   BY y.id IS NULL,x.id;

Для получения дополнительной помощи см. Почему следует Я предоставляю MCRE для того, что мне кажется очень простым SQL запросом

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

Для этого вы можете использовать оконные функции:

order by row_number() over (partition by product_id order by id)

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

order by (select count(*)
          from item_possession t2
          where t2.product_id = t.product_id and t2.id <= t.id
         )

В качестве альтернативы, вы можете использовать переменные - что требует сортировки дважды:

select ip.*
from (select ip.*,
             (@rn := if(@p = ip.product_id, @rn + 1,
                        if(@p := ip.product_id, 1, 1)
                       )
             ) as rn
      from (select ip.* from item_possession ip order by ip.product_id, ip.id
           ) ip cross join
           (select @p := -1, @rn := 0) params
     ) ip
order by rn, id;
0 голосов
/ 24 апреля 2020

Вы можете использовать row_number()

select t.*, row_number() over (partition by product_id order by id) as seq
from table t
order by seq, id;
...