Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Нормализуем данные / 5 сообщений из 5, страница 1 из 1
21.11.2014, 23:25:53
    #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
22.11.2014, 01:37:47
    #38813838
javajdbc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нормализуем данные
alexnews,

8434456

(Спасибо , Танглир. я нашел этот пост через ФАК)
...
Рейтинг: 0 / 0
24.11.2014, 19:10:22
    #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
24.11.2014, 19:14:14
    #38815510
alexnews
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нормализуем данные
alexnews,

Извиняюсь с первым примером проблема в слове team, там русская буква М, но все равно в выдаче она не учитывает последнее вхождение user_id, так что в принципе вывод остается тот же Пример 1 не правильный.
...
Рейтинг: 0 / 0
24.11.2014, 23:42:11
    #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
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Нормализуем данные / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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