powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как взять информацию с предыдущей строки и обновить текущую?
16 сообщений из 16, страница 1 из 1
Как взять информацию с предыдущей строки и обновить текущую?
    #39927968
Mellok14
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день, подскажите пожалуйста. Есть таблица:

CREATE TABLE car_generation(
id INT(8) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL UNIQUE,
id_car_model INT(8) NOT NULL REFERENCES car_model(id),
id_car_serie INT(8) NOT NULL REFERENCES car_serie(id),
year_begin YEAR NOT NULL,
year_end YEAR NOT NULL
);

Таблица заполнена с помощью фейкера. В ней year begin и year end приведены в порядок, так что year begin < year end.
Но нужно добавить логику годам, обновить их. Так, что в одной модели - генерации авто выпускались одна за одной.
Я попытался это сделать(принял, что одна генерация выпускается 3 года). Подскажите пожалуйста, что надо исправить, или вообще подход неправильный?
См. код:

CREATE PROCEDURE update_years()
BEGIN
UPDATE car_generation
SET year_begin OVER(ORDER BY id_car_model, name) = LEAD(year_end) OVER(ORDER BY id_car_model, name),
year_end OVER(ORDER BY id_car_model, name) = year_begin OVER(ORDER BY id_car_model, name) + 3
FROM car_generation WHERE id_car_model OVER(ORDER BY id_car_model, name) = LAG(id_car_model) OVER(ORDER BY id_car_model, name);
END//
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928013
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дайте INSERT INTO примера исходных данных и покажите конечный результат для этих данных, с пояснением, почему так.
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928014
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mellok14
что надо исправить
Синтаксис. Update обновляет поле, а не выражение. А OVER без оконной или агрегатной функции - вообще нонсенс.
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928022
entrypoint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mellok14,

вот из этой таблички и обновляйтесь

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
WITH 
car_generation AS 
(
    SELECT 1 AS id, 1 AS name, 1 AS id_car_model, 1 AS id_car_serie, 2017 AS year_begin, 2018 AS year_end  UNION ALL 
    SELECT 2 AS id, 1 AS name, 1 AS id_car_model, 1 AS id_car_serie, 2018 AS year_begin, 2019 AS year_end  UNION ALL 
    SELECT 3 AS id, 1 AS name, 1 AS id_car_model, 1 AS id_car_serie, 2019 AS year_begin, 2020 AS year_end  UNION ALL      
    SELECT 3 AS id, 1 AS name, 2 AS id_car_model, 2 AS id_car_serie, 2017 AS year_begin, 2018 AS year_end  UNION ALL 
    SELECT 4 AS id, 1 AS name, 2 AS id_car_model, 2 AS id_car_serie, 2018 AS year_begin, 2019 AS year_end  UNION ALL 
    SELECT 5 AS id, 1 AS name, 2 AS id_car_model, 2 AS id_car_serie, 2019 AS year_begin, 2020 AS year_end 

) 
SELECT 
	id, 
	name, 
	id_car_model, 
	id_car_serie, 
	year_begin, 
	year_end, 
	LAG(year_begin) OVER (PARTITION BY id_car_model, name ORDER BY year_begin ASC) AS year_begin_lag,
	LAG(year_end) OVER (PARTITION BY id_car_model, name ORDER BY year_begin ASC) AS year_end_lag		
FROM car_generation



Но лучше, тестовые данные и по-больше информации о ключах, сортировке и т.д и т.п.
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928031
Mellok14
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

INSERT INTO `car_generation` VALUES
('1','1 генерация','5','4','1983','2017'),
('2','3 генерация','1','8','1971','2015'),
('3','2 генерация','1','5','1998','2014'),
('4','1 генерация','1','7','1978','1982'),
('5','4 генерация','1','3','1978','2011'),
('6','2 герерация','5','2','1999','2002'),
('7','3 генерация','5','6','1983','1999'),

Хочу получить (если в отсортированнном виде по name и car_model и измененными годами):

('4','1 генерация','1','7','1978','1982'),
('3','2 генерация','1','5','1982','1985'),
('2','3 генерация','1','8','1985','1988'),
('5','4 генерация','1','3','1988','1991'),
('1','1 генерация','5','4','1983','2017'),
('6','2 герерация','5','2','2017','2019'),
('7','3 генерация','5','6','2019','2022'),
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928035
Mellok14
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
entrypoint
Mellok14,

вот из этой таблички и обновляйтесь

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
WITH 
car_generation AS 
(
    SELECT 1 AS id, 1 AS name, 1 AS id_car_model, 1 AS id_car_serie, 2017 AS year_begin, 2018 AS year_end  UNION ALL 
    SELECT 2 AS id, 1 AS name, 1 AS id_car_model, 1 AS id_car_serie, 2018 AS year_begin, 2019 AS year_end  UNION ALL 
    SELECT 3 AS id, 1 AS name, 1 AS id_car_model, 1 AS id_car_serie, 2019 AS year_begin, 2020 AS year_end  UNION ALL      
    SELECT 3 AS id, 1 AS name, 2 AS id_car_model, 2 AS id_car_serie, 2017 AS year_begin, 2018 AS year_end  UNION ALL 
    SELECT 4 AS id, 1 AS name, 2 AS id_car_model, 2 AS id_car_serie, 2018 AS year_begin, 2019 AS year_end  UNION ALL 
    SELECT 5 AS id, 1 AS name, 2 AS id_car_model, 2 AS id_car_serie, 2019 AS year_begin, 2020 AS year_end 

) 
SELECT 
	id, 
	name, 
	id_car_model, 
	id_car_serie, 
	year_begin, 
	year_end, 
	LAG(year_begin) OVER (PARTITION BY id_car_model, name ORDER BY year_begin ASC) AS year_begin_lag,
	LAG(year_end) OVER (PARTITION BY id_car_model, name ORDER BY year_begin ASC) AS year_end_lag		
FROM car_generation



Но лучше, тестовые данные и по-больше информации о ключах, сортировке и т.д и т.п.



Подскажите смысл этого представления:
SELECT 1 AS id, 1 AS name, 1 AS id_car_model, 1 AS id_car_serie, 2017 AS year_begin, 2018 AS year_end……
А если там тысячи строк?
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928040
Mellok14
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina
Mellok14
что надо исправить
Синтаксис. Update обновляет поле, а не выражение. А OVER без оконной или агрегатной функции - вообще нонсенс.


Про update понял. Если найдется время, не могли бы подправить запрос, я что-то запутался.
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928045
entrypoint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mellok14,
entrypoint

Подскажите смысл этого представления:
SELECT 1 AS id, 1 AS name, 1 AS id_car_model, 1 AS id_car_serie, 2017 AS year_begin, 2018 AS year_end……
А если там тысячи строк?

это те тестовые данные, которые вы не представили, желая получить решение
а вот это
Код: plsql
1.
2.
LAG(year_begin) OVER (PARTITION BY id_car_model, name ORDER BY year_begin ASC) AS year_begin_lag,
LAG(year_end) OVER (PARTITION BY id_car_model, name ORDER BY year_begin ASC) AS year_end_lag	


ответ на вопрос
Mellok14Как взять информацию с предыдущей строки
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928049
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mellok14
Я вижу
Код: sql
1.
name VARCHAR(255) NOT NULL UNIQUE,

и это не очень согласуется с показанными исходными данными.
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928052
Mellok14
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina
Mellok14
Я вижу
Код: sql
1.
name VARCHAR(255) NOT NULL UNIQUE,

и это не очень согласуется с показанными исходными данными.


Да, слишком много ошибок. Надо дорабатывать.
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928053
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mellok14
('6','2 герерация','5','2','2017','2019'),
Почему тут разность 2, если в остальных случаях сделано 3?
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928054
Mellok14
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
entrypoint
Mellok14,
entrypoint

Подскажите смысл этого представления:
SELECT 1 AS id, 1 AS name, 1 AS id_car_model, 1 AS id_car_serie, 2017 AS year_begin, 2018 AS year_end……
А если там тысячи строк?

это те тестовые данные, которые вы не представили, желая получить решение
а вот это
Код: plsql
1.
2.
LAG(year_begin) OVER (PARTITION BY id_car_model, name ORDER BY year_begin ASC) AS year_begin_lag,
LAG(year_end) OVER (PARTITION BY id_car_model, name ORDER BY year_begin ASC) AS year_end_lag	


ответ на вопрос
Mellok14Как взять информацию с предыдущей строки


Спасибо, а уже потом делаем UPDATE из этой таблицы?
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928055
Mellok14
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina
Mellok14
('6','2 герерация','5','2','2017','2019'),
Почему тут разность 2, если в остальных случаях сделано 3?


Опечатался, этот пример написан вручную.
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928059
entrypoint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mellok14,

Да, а из этой таблицы обновляемся, главное правильно определить поля, которые входят в PARTITION BY и ORDER BY
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928064
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
WITH cte1 AS 
(
SELECT *, 
       ROW_NUMBER() OVER (PARTITION BY id_car_model ORDER BY name ASC) rn
FROM car_generation
),
cte2 AS 
(
SELECT DISTINCT
       id_car_model, 
       FIRST_VALUE(year_end) OVER (PARTITION BY id_car_model ORDER BY name ASC) end1
FROM car_generation
)
SELECT cte1.id, 
       cte1.name, 
       cte1.id_car_model, 
       cte1.id_car_serie,
       CASE WHEN cte1.rn=1 THEN cte1.year_begin
                           ELSE cte2.end1 + 3 * (rn - 2)
                           END year_begin,
       CASE WHEN cte1.rn=1 THEN cte1.year_end
                           ELSE cte2.end1 + 3 * (rn - 1)
                           END year_end
FROM cte1
JOIN cte2 USING (id_car_model)
ORDER BY cte1.id_car_model, cte1.name;


fiddle
...
Рейтинг: 0 / 0
Как взять информацию с предыдущей строки и обновить текущую?
    #39928072
Mellok14
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
WITH cte1 AS 
(
SELECT *, 
       ROW_NUMBER() OVER (PARTITION BY id_car_model ORDER BY name ASC) rn
FROM car_generation
),
cte2 AS 
(
SELECT DISTINCT
       id_car_model, 
       FIRST_VALUE(year_end) OVER (PARTITION BY id_car_model ORDER BY name ASC) end1
FROM car_generation
)
SELECT cte1.id, 
       cte1.name, 
       cte1.id_car_model, 
       cte1.id_car_serie,
       CASE WHEN cte1.rn=1 THEN cte1.year_begin
                           ELSE cte2.end1 + 3 * (rn - 2)
                           END year_begin,
       CASE WHEN cte1.rn=1 THEN cte1.year_end
                           ELSE cte2.end1 + 3 * (rn - 1)
                           END year_end
FROM cte1
JOIN cte2 USING (id_car_model)
ORDER BY cte1.id_car_model, cte1.name;


fiddle


Не знаю, откуда у вас столько альтруизма, но спасибо вам огромное!
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как взять информацию с предыдущей строки и обновить текущую?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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