Изменение порядка записей с использованием SQL-запроса (переписать в один запрос) - PullRequest
0 голосов
/ 02 октября 2018

У меня есть таблица sliders.

+----+-----+---------+
| id | pos | content |
+----+-----+---------+
| 1  | 0   | image   |
+----+-----+---------+
| 2  | 1   | image   |
+----+-----+---------+
| 3  | 2   | video   |
+----+-----+---------+
| 4  | 3   | video   |
+----+-----+---------+
| 5  | 4   | image   |
+----+-----+---------+

То, что я хотел, чтобы эти записи были в следующем порядке:

  1. Изображение
  2. Видео
  3. ... все остальное

В настоящее время у меня есть позиция столбца pos.Он упорядочен по номеру, в котором 0 является первым, а наибольшее - последним.

Мне нужно изменить его порядок, используя один запрос, но в настоящее время я использую 3 запроса для этого.

Во-первых, это: UPDATE sliders SET pos = pos + 2

Это вернет:

+----+-----+---------+
| id | pos | content |
+----+-----+---------+
| 1  | 2   | image   |
+----+-----+---------+
| 2  | 3   | image   |
+----+-----+---------+
| 3  | 4   | video   |
+----+-----+---------+
| 4  | 5   | video   |
+----+-----+---------+
| 5  | 6   | image   |
+----+-----+---------+

Затем я найду первое видео и первое изображение, чтобы установить их положение как первое и второе.

UPDATE sliders SET pos = 0 WHERE id = (SELECT MIN(id) FROM sliders WHERE content='image')
UPDATE sliders SET pos = 1 WHERE id = (SELECT MIN(id) FROM sliders WHERE content='video')

Это вернется:

+----+-----+---------+
| id | pos | content |
+----+-----+---------+
| 1  | 0   | image   |
+----+-----+---------+
| 2  | 2   | image   |
+----+-----+---------+
| 3  | 1   | video   |
+----+-----+---------+
| 4  | 5   | video   |
+----+-----+---------+
| 5  | 6   | image   |
+----+-----+---------+

Я не против, если есть пробелы, пока это в порядке.

Вопрос в том, есть лиДругой способ сделать это, если возможно, один запрос без пробелов или что-нибудь?

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

+----+-----+---------+
| id | pos | content |
+----+-----+---------+
| 1  | 0   | image   |
+----+-----+---------+
| 2  | 2   | image   |
+----+-----+---------+
| 3  | 1   | video   |
+----+-----+---------+
| 4  | 3   | video   |
+----+-----+---------+
| 5  | 4   | image   |
+----+-----+---------+

Если нет другого пути, я думаю, яможно придерживаться 3 запросов.

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Я думаю, что это не может обновить один запрос, потому что мы должны знать min(pos), но pos должно быть обновлено.
И mysql не может использовать with.
Так что если выможно сделать вид, возможно, это возможно.

Это вид.
new_pos col - новая позиция.(1. изображение, 2. видео, и вы не возражаете, если есть пробелы ...)

create view newSliders as (
select id,
       pos,
       case content when 'image' then case pos when (select min(pos) from sliders where content = 'image') then 0
                                               else pos+2
                                      end
                    when 'video' then case pos when (select min(pos) from sliders where content = 'video') then 1
                                               else pos++2
                                      end
       end as new_pos,
       content
  from sliders
)

и это единственный запрос на обновление.

update sliders
   set pos = (select new_pos from newSliders where id = sliders.id);

Надеюсьэто помогает вам.

0 голосов
/ 02 октября 2018

Это сделает это за вас на сервере sql.Вы должны будете изменить предложение over в mysql.

Сначала создать тестовые данные:

declare @t table(id int, pos int, content varchar(20))
insert @t values (1,0,'image')
,(2,1,'image')
,(3,2,'video')
,(4,3,'other')
,(5,4,'image')
select * from @t

id  pos content
1   0   image
2   1   image
3   2   video
4   3   other
5   4   image

Выполнить обновление, используя row_number

;with t as (
    select id, content, pos,
    row_number() over(order by case content when 'image' then 1 when 'video' then 2 else 3 end,id) rn
    from @t
)
update t set pos=rn

Результат:

select * from @t

id  pos content
1   1   image
2   2   image
3   4   video
4   5   other
5   3   image

Если вы используете старую версию mysql, которая не поддерживает CTE, то это делает то же самое:

update t set pos=p.rn
from @t t
join (
    select id, content, pos,
    row_number() over(order by case content when 'image' then 1 when 'video' then 2 else 3 end,id) rn
    from @t
) p on p.id=t.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...