powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Можно ли решить данную задачу одним SQL запросом?
10 сообщений из 10, страница 1 из 1
Можно ли решить данную задачу одним SQL запросом?
    #39201479
kormot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!

Немного коряво оформил свой предыдущий топик про HAVING, наверное поэтому там так и не дали ни советов ни ответов.
Сформулирую всё здесь по возможности ясно и понятно.

Итак есть таблица описывающая элементы. У каждого элемента есть координаты: Строка ( row ) и Столбец ( col ) - это целые числа, а также свойство Длина ( len ) - тоже целое.

Т.е. каждый элемент занимает в своей строке клетки начиная с col до col+len. В строках никакие два элемента не пересекаются. Расположены элементы не обязательно вплотную друг к другу.

Таблица описывающая эти элементы:
Код: sql
1.
2.
3.
4.
5.
6.
TABLE elements (
   id    SERIAL,
   row   INT UNSIGNED NOT NULL,
   col   INT UNSIGNED NOT NULL,
   len   INT UNSIGNED NOT NULL
)



Так вот задача состоит в том, чтобы сдвинуть данный элемент вправо.
Казалось бы в чём проблема? Увеличиваем его col на единицу и дело с концом. Но проблема в том, что элементы не должны пересекаться. Поэтому надо в случае если вплотную к данному элементу справа стоит другой элемент, сдвинуть и его. А если и у того вплотную сосед .... и так далее.

Мысль как это решить такая: Надо сдвинуть вправо все элементы для которых выполняются условия:
Элемент находится в одной строке с искомым. (a1.row=a2.row)

Элемент находится правее искомого (a2.col>a1.col)

Сумма длин всех элементов от искомого до данного SUM(aa.len) (все элементы у которых a1.col<=aa.col<=a2.col ) равно разнице ( a2.col + a2.len - a1.col )

Где a1 - это искомый элемент, который надо сдвинуть вправо
a2 - элементы которые непрерывно вплотную с искомым a1.

Помогите мне решить эту задачу. Вроде звучит просто, а записать это в SQL запросе что-то не удаётся.
...
Рейтинг: 0 / 0
Можно ли решить данную задачу одним SQL запросом?
    #39201628
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kormot,

1) самое простое передвигать всех сразу.
2) .... и так далее. -> просто используй рекурсию
...
Рейтинг: 0 / 0
Можно ли решить данную задачу одним SQL запросом?
    #39201656
kormot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab,

очень лаконично. Я не очень понял что предполагается делать.

1. Проще передвинуть всех, это в смысле передвинуть всех что правее неважно вплотную они к этому элементу? Это не решение задачи.
2. Рекурсию, это получается рекурсия процедурой MySQL'ной? В смысле передаём в функцию ID элемента который хотим двинуть, он ищет для него ближайшего правого соседа и если этот сосед вплотную, то вызываем процедуру уже для этого соседа, а если не вплотную, то просто двигаем элемент.

Надо посмотреть этот вариант.
...
Рейтинг: 0 / 0
Можно ли решить данную задачу одним SQL запросом?
    #39201665
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kormot1. Проще передвинуть всех, это в смысле передвинуть всех что правее неважно вплотную они к этому элементу? Это не решение задачи.Где в условии сказано, что это не решение?
...
Рейтинг: 0 / 0
Можно ли решить данную задачу одним SQL запросом?
    #39201760
kormot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglir, вы всегда предлагаете решить другую задачу когда не можете решить предложеную? Тоже вариант. Но мне он не подходит.
...
Рейтинг: 0 / 0
Можно ли решить данную задачу одним SQL запросом?
    #39201873
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kormot,

приведите пример набора данных и итоговый набор

если у вас есть Коорд row/col то как понимать это -
авторТ.е. каждый элемент занимает в своей строке клетки начиная с col до col+len
...
Рейтинг: 0 / 0
Можно ли решить данную задачу одним SQL запросом?
    #39202011
kormot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_Ustinovkormot,

приведите пример набора данных и итоговый набор

если у вас есть Коорд row/col то как понимать это -
авторТ.е. каждый элемент занимает в своей строке клетки начиная с col до col+len

Набор данных:
Код: sql
1.
2.
3.
4.
5.
6.
7.
| id      | row     | col     | len       |
-------------------------------------------
| 1       | 1       | 1       | 1         | - эл-т в 1 строке, 1 колонке, размером в 1 "клетку". Т.е. занимает отрезок по горизонтали [1,2]
| 2       | 1       | 2       | 5         | - эл-т в 1 строке, 2 колонке, размером в 5 "клеток". Т.е. занимает отрезок по горизонтали [2,7]
| 3       | 1       | 10      | 2         | - эл-т в 1 строке, 10 колонке, размером в 2 "клетки". Т.е. занимает отрезок по горизонтали [10,12]
| 4       | 1       | 12      | 1         | - эл-т в 1 строке, 12 колонке, размером в 1 "клетку". Т.е. занимает отрезок по горизонтали [12,13]
| 5       | 1       | 13      | 6         | - эл-т в 1 строке, 13 колонке, размером в 6 "клеток". Т.е. занимает отрезок по горизонтали [13,19]


Так вот из этого набора данных, "вплотную" стоят эл-ты id=1,id=2 также вплотную друг к другу стоят элементы с id=3,id=4,id=5

Теперь пример результата для операции над элементом:
Допустим я хочу провести операцию над элементом id=1.
Сформулирую её: Надо сдвинуть вправо на 1 клетку все элементы которые поочерёдно "вплотную" с id=1. Таких только один, это: id=2, т.е. результат выполнения задачи над id=1 будет:
Код: sql
1.
2.
3.
4.
5.
6.
7.
| id      | row     | col     | len       |
-------------------------------------------
| 1       | 1       | 1       | 1         |
| 2       | 1       | 3       | 5         | * Сместился только этот элемент
| 3       | 1       | 10      | 2         |
| 4       | 1       | 12      | 1         |
| 5       | 1       | 13      | 6         |


Замечу что сам элемент для которого производим операцию не смещается. Но это уже мелочи.
Теперь для наглядности, приведу пример для id=3. С ним вплотную стоят id=4 и id=5, т.е. результат будет (при исходных данных, а не после операции над id=1 ):
Код: sql
1.
2.
3.
4.
5.
6.
7.
| id      | row     | col     | len       |
-------------------------------------------
| 1       | 1       | 1       | 1         |
| 2       | 1       | 2       | 5         |
| 3       | 1       | 10      | 2         |
| 4       | 1       | 13      | 1         | * Сместился
| 5       | 1       | 14      | 6         | * Сместился


Это как бруски данной длины расположеные вдоль строки тетрадки в клеточку, где длина бруска кратна клеточкам этой тетради и смещая один брусок, он толкнёт те, которые вплотную с ним.
...
Рейтинг: 0 / 0
Можно ли решить данную задачу одним SQL запросом?
    #39202220
kormot, Если только по горизонтали, то как-то так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
update elements e1 RIGHT JOIN (
  select s_e1_.*, @myvar:=col+len as _my_var_
  from elements s_e1_, (select @myvar:=999) fake_
  where id>3 and col <= @myvar
  order by id ASC, @myvar 
) e2 USING(id)
SET e1.col=e1.col+1;



'999' поменять на число, которое гарантированно больше изначальной позиции ('col');
'id>3' - тут указано от какого id начинать смещение.
...
Рейтинг: 0 / 0
Можно ли решить данную задачу одним SQL запросом?
    #39202305
kormot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Громыхатель, попробую твой запрос тоже. А пока по наущению mini.weblab сварганил вариант не в один запрос, а с помощью рекурсивной процедуры. Заодно и с процедурами научился работать. А то до этого момента ни разу не использовал.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
CREATE PROCEDURE	elMove(IN elementID BIGINT, IN moveDir TINYINT, IN recLevel TINYINT, OUT nextID BIGINT) 
BEGIN
   DECLARE  data   BIGINT UNSIGNED;
   SET      max_sp_recursion_depth=50;
   /*Получаем ближайшего соседа*/ 
   SELECT   aa.id INTO nextID
   FROM     elements      AS aa
   JOIN     elements      AS bb ON bb.rowID=aa.rowID
   WHERE    bb.id=elementID 
      AND   bb.col+bb.len = aa.col;
   /*Если результат не нулевой, то рекурсивно вызываем для найденого элемента*/ 
   IF nextID > 0 THEN 
      CALL     elMove(nextID, moveDir, recLevel+1, data);
   END IF;
   /*Если это вызов не нулевого уровня, то двигаем элемент*/
   IF recLevel > 0 THEN 
      UPDATE   elements	AS aa 
      SET      aa.col = aa.col + 1
      WHERE    aa.id=elementID;
   END IF;
END


Тут дополнительные аргументы в процедуре, это moveDir - чтобы двигать влево или вправо от данного. Пока не используется, но тут уже дело за малым.
Всем спасибо!
...
Рейтинг: 0 / 0
Можно ли решить данную задачу одним SQL запросом?
    #39202658
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kormottanglir, вы всегда предлагаете решить другую задачу когда не можете решить предложеную?Какие далеко идущие выводы... позвольте поинтересоваться, на каком основании вы их сделали?
авторТоже вариант. Но мне он не подходит.Вот я и пытался намекнуть на то, что условие задачи лучше оглашать сразу целиком, чтобы потом не отписываться от неподходящих решений.
PS. Ряды у вас не длинные? Можете упереться в recursive limit.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Можно ли решить данную задачу одним SQL запросом?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]