powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Нормализуем данные
5 сообщений из 5, страница 1 из 1
Нормализуем данные
    #38813788
Фотография alexnews
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть таблица:

Код: html
1.
2.
3.
4.
id category
1 10,20,30,15,22,23
2 11,12,13,56
3 45,34,222, 34



Код: plsql
1.
2.
CREATE TABLE testpub1 (id int(10) NOT NULL, category varchar(100) DEFAULT NULL);
INSERT INTO testpub1 VALUE (1,'10,20,15,22,23'), (2,'11,12,13,56'),(3,'45,34,222,34');



Нужно из нее сделать нормализованные две таблицы

Код: xml
1.
CREATE TABLE testpub2 (id int(9) NOT NULL, category_id int(9) NOT NULL);



Можно ли это сделать инструментами MySQL?
...
Рейтинг: 0 / 0
Нормализуем данные
    #38813838
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexnews,

8434456

(Спасибо , Танглир. я нашел этот пост через ФАК)
...
Рейтинг: 0 / 0
Нормализуем данные
    #38815505
Фотография alexnews
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javajdbc,
Спасибо javajdbc. Ссылка очень и очень супер,

Код: plsql
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.
CREATE TABLE team(
  id INT NOT NULL AUTO_INCREMENT,
  users_id VARCHAR(50),
  NAME VARCHAR(10),
  PRIMARY KEY (id)
)ENGINE=INNODB;

CREATE TABLE USER(
  id INT NOT NULL AUTO_INCREMENT, 
  NAME VARCHAR(10), 
  PRIMARY KEY (id)
)ENGINE=INNODB;

INSERT INTO USER(NAME)
SELECT SUBSTRING(MD5(RAND()), -8) FROM
(SELECT 1 a UNION ALL SELECT 2 a UNION ALL SELECT 3 a UNION ALL SELECT 4 a) a,
(SELECT 1 a UNION ALL SELECT 2 a UNION ALL SELECT 3 a UNION ALL SELECT 4 a) b,
(SELECT 1 a UNION ALL SELECT 2 a UNION ALL SELECT 3 a UNION ALL SELECT 4 a) c;

INSERT INTO team(users_id, NAME )
VALUES
('1,5,6,7','team1'),
('0,13,666,7','team2'),
('11,52,63,74','team3'),
('','team4'),
('5,5,7,8,9,0,11,22','team5');




одна проблема
пример 1

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT tt.id team_id, tt.name team_name, tt.users_id,
u.id user_id, u.name user_name 
FROM
(
SELECT *, SUBSTRING_INDEX(SUBSTRING_INDEX(team.users_id, ',',z.x),',',-1) uid
FROM TEAМ
JOIN (SELECT 1 X UNION SELECT 2 UNION SELECT 3) z ON 1=1
) tt
LEFT JOIN USER u ON u.id = uid
WHERE u.id IS NOT NULL



не заработал и моих навыков не хватило чтобы этот пример запустить

Пример 2

Код: plsql
1.
2.
3.
4.
SELECT tt.id team_id, tt.name team_name, tt.users_id,
u.id user_id, u.name user_name
FROM team tt LEFT JOIN USER u 
ON tt.users_id LIKE CONCAT('%',U.id,',%') 



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

Код: plsql
1.
2.
3.
INSERT INTO team(users_id, NAME )
VALUES
('1,11,43,44,33','team6');



и сразу видно по результату появление сатегорий которые проходят по маске %id,% а это почти все 1,2,3,4 и так далее категории

Пример 3
Код: plsql
1.
2.
3.
4.
EXPLAIN SELECT tt.id team_id, tt.name team_name, tt.users_id,
u.id user_id, u.name user_name
FROM team tt LEFT JOIN USER u 
ON FIND_IN_SET(U.id, REPLACE(tt.users_id, ' ', '')) != 0;



сработал на все 100%.
Спасибо еще раз, надеюсь кому-то сохранил время на поиск решения аналогичной проблемы.
...
Рейтинг: 0 / 0
Нормализуем данные
    #38815510
Фотография alexnews
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexnews,

Извиняюсь с первым примером проблема в слове team, там русская буква М, но все равно в выдаче она не учитывает последнее вхождение user_id, так что в принципе вывод остается тот же Пример 1 не правильный.
...
Рейтинг: 0 / 0
Нормализуем данные
    #38815659
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexnews,

Все работает как надо, просто с переменными
всегда надо аккуратно.

В изначальном примере имеется 64 реальных юзера
(с ид от 1 до 64) и , как отмечено в исходном посте,
только 3-шаговый вектор.
Т.е. пример проходит только по первым 3 вхождениям.
Кроме того, будут убраны "0", "73", "666".
Правда иходный код не уберет дубликаты.

ВОт пример где поинтер увеличен до 6 шагов и
добавлен ГРОУП БУ чтобы убрать дубликаты.

И все равно, для наглядности ограничения этого подхода,
поинтер недошел до конца вот этой строчки:
"5,5,7,8,9,0,11,22"

Т.е. надо заранее знать максимальную длину вектора.

http://sqlfiddle.com/#!2/dafbe9/10

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
select * from
(
SELECT tt.id team_id, tt.name team_name, tt.users_id,
u.id user_id, u.name user_name 
FROM
(
SELECT *, SUBSTRING_INDEX(SUBSTRING_INDEX(team.users_id, ',',z.a),',',-1) uid
FROM TEAm
JOIN (SELECT 1 a UNION SELECT 2 a UNION SELECT 3 a
     UNION SELECT 4 a UNION SELECT 5 a UNION SELECT 6 a) z ON 1=1
) tt
LEFT JOIN USER u ON u.id = uid
WHERE u.id IS NOT NULL 
) w 
group by team_id, user_id
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Нормализуем данные
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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