SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 31.03.2007 14:02:45

vanno
Участник
Зарегистрирован: 31.03.2007
Сообщений: 7

ПОМОГИТЕ написать запрос

Здравствуйте!
Пожалуйста, помогите!
Такая задача. Есть форум. Самописный. Сейчас на сайт поставили новый форум (SMF).
Необходимо перенести ВСЕ темы и сообщения со старого на новый.
В таблице старого форума 37233 записи.
В SMF используется две основные таблицы под темы и сообщения, в старом форуме одна общая.
Структуры таблиц можно скачать отсюда:
http://sql.ru/forum/actualfile.aspx?id=3955453
К каждому полю я сделал комменты.

Идея такова:
В старом форуме (таблица ibs_forum_items) хранятся и темы и сами сообщения.
Если значения полей id = thread_id, то эта запись - тема.
Сообщениями этой темы являются те записи, у которых thread_id = id темы.
Т.е. по запросу
SELECT *
FROM `ibs_forum_items`
WHERE id = thread_id
я получаю темы.
Далее необходимо эту инфу распихать по двум таблицам базы SMF smf_topics и smf_messages (по структуре будет понятно, что куда).
После чего уже заполнять smf_message записями, содержащими сообщения..
Не знаю, на сколько хорошо я объяснил, но очень прошу, ПОМОГИТЕ!
Если нужна доп. инфа - пишите на vanno@list.ru
Заранее всем большое спасибо!

Неактивен

 

#2 31.03.2007 15:23:12

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6732

Re: ПОМОГИТЕ написать запрос

Во-первых, Вам нужно перенести темы. Советую сохранить их потоковые
номера, так Вам будет легче потом с ними работать:

INSERT INTO smf_topics (id_topic, id_first_msg)
SELECT id, id
FROM ibs_forum_items
WHERE thread_id = id

Во-вторых, Вам нужно перенести сообщения

INSERT INTO smf_messages (id_msg, id_topic, [поля, отображаемые в форуме: subject, ...])
SELECT id, thread_id, [аналогичные поля старой таблицы]
FROM ibs_forum_items

После этого, Вам необходимо обновить некоторую статистику
в таблице тем: количество строк, номер последнего сообщения и пр.
Количество строк, например, можно обновить запросом
UPDATE smf_topics t SET numreplies =
  (SELECT count(*) FROM smf_messages WHERE id_topic = t.id_topic)

Неактивен

 

#3 01.04.2007 13:16:03

vanno
Участник
Зарегистрирован: 31.03.2007
Сообщений: 7

Re: ПОМОГИТЕ написать запрос

Спасибо большое, paulus!
Вы единственный, кто откликнулся на мою просьбу.
Завтра попробую smile
Всего Вам хорошего!

Неактивен

 

#4 02.04.2007 09:16:47

vanno
Участник
Зарегистрирован: 31.03.2007
Сообщений: 7

Re: ПОМОГИТЕ написать запрос

Уважаемый, paulus!
Есть проблема.
Дело в том, что при
INSERT INTO smf_topics (id_topic, id_first_msg)
SELECT id, id
FROM ibs_forum_items
WHERE thread_id = id

выскакивает ошибка
#1062 - Duplicate entry '0-0' for key 2

Видимо это из-за того, что в новом форуме в таблицах
smf_topics и smf_messages ключевые поля  - auto_increment
А нам необходимо явно указать значение этого поля...
Можно ли решить эту проблему?

Неактивен

 

#5 02.04.2007 09:44:57

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3857

Re: ПОМОГИТЕ написать запрос

Уважаемый vanno,

Повтор здесь происходит для второго ключа (key 2), причем, судя по значению 0-0, этот ключ составной, уникальный и  составлен из полей, которые мы не вставляем в таблицу. Чтобы можно было понять причину ошибки, пришлите пожалуйста результат выполнения
SHOW CREATE TABLE smf_topics

и также желательно

SHOW CREATE TABLE smf_messages
SHOW CREATE TABLE ibs_forum_items

Неактивен

 

#6 02.04.2007 10:01:36

vanno
Участник
Зарегистрирован: 31.03.2007
Сообщений: 7

Re: ПОМОГИТЕ написать запрос

CREATE TABLE `smf_topics` (
`ID_TOPIC` mediumint(8) unsigned NOT NULL auto_increment,
`isSticky` tinyint(4) NOT NULL default '0',
`ID_BOARD` smallint(5) unsigned NOT NULL default '0',
`ID_FIRST_MSG` int(10) unsigned NOT NULL default '0',
`ID_LAST_MSG` int(10) unsigned NOT NULL default '0',
`ID_MEMBER_STARTED` mediumint(8) unsigned NOT NULL default '0',
`ID_MEMBER_UPDATED` mediumint(8) unsigned NOT NULL default '0',
`ID_POLL` mediumint(8) unsigned NOT NULL default '0',
`numReplies` int(10) unsigned NOT NULL default '0',
`numViews` int(10) unsigned NOT NULL default '0',
`locked` tinyint(4) NOT NULL default '0',
PRIMARY KEY  (`ID_TOPIC`),
UNIQUE KEY `lastMessage` (`ID_LAST_MSG`,`ID_BOARD`),
UNIQUE KEY `firstMessage` (`ID_FIRST_MSG`,`ID_BOARD`),
UNIQUE KEY `poll` (`ID_POLL`,`ID_TOPIC`),
KEY `isSticky` (`isSticky`),
KEY `ID_BOARD` (`ID_BOARD`)
) TYPE=MyISAM

//----------------------------------------------------------------------

CREATE TABLE `smf_messages` (
`ID_MSG` int(10) unsigned NOT NULL auto_increment,
`ID_TOPIC` mediumint(8) unsigned NOT NULL default '0',
`ID_BOARD` smallint(5) unsigned NOT NULL default '0',
`posterTime` int(10) unsigned NOT NULL default '0',
`ID_MEMBER` mediumint(8) unsigned NOT NULL default '0',
`ID_MSG_MODIFIED` int(10) unsigned NOT NULL default '0',
`subject` tinytext NOT NULL,
`posterName` tinytext NOT NULL,
`posterEmail` tinytext NOT NULL,
`posterIP` tinytext NOT NULL,
`smileysEnabled` tinyint(4) NOT NULL default '1',
`modifiedTime` int(10) unsigned NOT NULL default '0',
`modifiedName` tinytext NOT NULL,
`body` text NOT NULL,
`icon` varchar(16) NOT NULL default 'xx',
PRIMARY KEY  (`ID_MSG`),
UNIQUE KEY `topic` (`ID_TOPIC`,`ID_MSG`),
UNIQUE KEY `ID_BOARD` (`ID_BOARD`,`ID_MSG`),
UNIQUE KEY `ID_MEMBER` (`ID_MEMBER`,`ID_MSG`),
KEY `ipIndex` (`posterIP`(15),`ID_TOPIC`),
KEY `participation` (`ID_MEMBER`,`ID_TOPIC`),
KEY `showPosts` (`ID_MEMBER`,`ID_BOARD`),
KEY `ID_TOPIC` (`ID_TOPIC`)
) TYPE=MyISAM

//---------------------------------------------------------------------

CREATE TABLE `ibs_forum_items` (
`id` int(11) NOT NULL auto_increment,
`service_id` int(11) NOT NULL default '0',
`node_id` int(11) NOT NULL default '0',
`parent_id` int(11) NOT NULL default '0',
`thread_id` int(11) NOT NULL default '0',
`user_id` int(11) NOT NULL default '0',
`name` varchar(50) NOT NULL default '',
`email` varchar(50) NOT NULL default '',
`ip` varchar(16) NOT NULL default '',
`title` varchar(255) NOT NULL default '',
`body` text NOT NULL,
`date` int(11) NOT NULL default '0',
`replies` int(11) NOT NULL default '0',
`lastdate` int(11) NOT NULL default '0',
`is_active` tinyint(1) NOT NULL default '0',
`is_open` tinyint(1) NOT NULL default '0',
`email_notify` tinyint(4) NOT NULL default '0',
`spy_thread` tinyint(1) NOT NULL default '0',
`is_subscribed` tinyint(1) NOT NULL default '0',
`position` int(11) NOT NULL default '0',
`global_order` int(11) NOT NULL default '0',
`level` int(11) NOT NULL default '0',
`num_child` int(11) default NULL,
PRIMARY KEY  (`id`),
KEY `node_id` (`node_id`),
KEY `name` (`name`),
KEY `date` (`date`),
KEY `replies` (`replies`),
KEY `lastdate` (`lastdate`),
KEY `position` (`position`),
KEY `parent_id` (`parent_id`),
KEY `thread_id` (`thread_id`),
KEY `is_active` (`is_active`),
KEY `is_open` (`is_open`),
KEY `global_order` (`global_order`),
KEY `level` (`level`),
KEY `num_child` (`num_child`)
) TYPE=MyISAM

Неактивен

 

#7 02.04.2007 10:21:56

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3857

Re: ПОМОГИТЕ написать запрос

У Вас вставляется повторное значение ключа:
UNIQUE KEY `lastMessage` (`ID_LAST_MSG`,`ID_BOARD`)

Ключи составные уникальные. Это значит, что пары полей, перечисленных при объявлении ключа должны быть уникальными.
Чтобы исправить ошибку нам потребуется указать явно значение ID_LAST_MSG.
Можно начать с того, что указать его равным номеру первого сообщения, а потом пересчитать значение ID_LAST_MSG

(перед выполнением запроса очистите содержимое новой таблицы, TRUNCATE smf_topics)

INSERT INTO smf_topics (id_topic, id_first_msg, id_last_msg)
SELECT id, id, id
FROM ibs_forum_items
WHERE thread_id = id

в таком случае потребуется вычислить правильное значение id_last_msg, что можно сделать с помощью запроса:

UDATE smf_topics s SET id_last_msg=(SELECT i.id from ibs_forum_items i WHERE i.thread_id=s.id_topic ORDER BY i.id desc LIMIT 1)

Неактивен

 

#8 02.04.2007 10:33:51

vanno
Участник
Зарегистрирован: 31.03.2007
Сообщений: 7

Re: ПОМОГИТЕ написать запрос

INSERT INTO smf_topics (id_topic, id_first_msg, id_last_msg)
SELECT id, id, id
FROM ibs_forum_items
WHERE thread_id = id
прошло успешно, однако

UPDATE smf_topics s SET id_last_msg=(SELECT i.id FROM ibs_forum_items i WHERE i.thread_id=s.id_topic ORDER BY i.id desc LIMIT 1)

возвращает сделующее:
#1064 - You have an error in your SQL syntax.  Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT i.id from ibs_forum_items i WHERE i.thread_id=s.id_topic

Неактивен

 

#9 02.04.2007 12:52:50

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6732

Re: ПОМОГИТЕ написать запрос

А у Вас сервер какой версии?

Неактивен

 

#10 05.04.2007 12:20:50

vanno
Участник
Зарегистрирован: 31.03.2007
Сообщений: 7

Re: ПОМОГИТЕ написать запрос

Apache/1.3.37
MySQL 4.0.24

Неактивен

 

#11 05.04.2007 17:56:41

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 834

Re: ПОМОГИТЕ написать запрос

vanno написал:

Apache/1.3.37
MySQL 4.0.24

У Вас не работает вот этот

vanno написал:

UPDATE smf_topics s SET id_last_msg=(SELECT i.id FROM ibs_forum_items i WHERE i.thread_id=s.id_topic ORDER BY i.id desc LIMIT 1)

запрос, т.к. в нем содержится подзапрос, а поддержка подзапросов добавлена, начиная с версии MySQL 4.1.

Чтобы эту проблему решить, нужно либо как-то переписать запрос через JOIN, либо обновить сервер MySQL.

Неактивен

 

#12 05.04.2007 21:02:18

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6732

Re: ПОМОГИТЕ написать запрос

Через JOIN Вам, видимо, прийдется переписывать с помощью временной таблицы.
Вам не удастся сделать UPDATE + JOIN + групповая операция (MAX).

Я бы сделал что-то типа

CREATE TABLE maxids
SELECT MAX(id) as id, thread_id
FROM ibs_forum_items
GROUP BY thread_id

и потом с этой таблицей уже обновление

UPDATE smf_topics s, maxids m
SET id_last_msg=m.id
WHERE s.id_topic = m.thread_id

Неактивен

 

#13 19.04.2007 14:02:06

vanno
Участник
Зарегистрирован: 31.03.2007
Сообщений: 7

Re: ПОМОГИТЕ написать запрос

Всем большое спасибо!
Вы мне очень очень помогли!
Теперь я буду часто заходить на этот форум - здесь действительно хорошие специалисты. smile

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson