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

Имеются 2 таблицы вида:
1) Главная (main_table)
id_t (int) | parent (varchar) | price (int)
Пример данных:
1 | '' | 198
2 | '' | 50
3 | '' | 167
2) С дополняющими данными (part_table)
id_p (int) | id_t (int) | part (varchar)
Пример данных:
1 | 1 | 'гвоздь'
2 | 1 | 'доска'
3 | 1 | 'гайка'
4 | 1 | 'шуруп'
5 | 1 | 'болт'
6 | 2 | 'саморез'
7 | 2 | 'дсп'
8 | 2 | 'лампа'
9 | 2 | 'балка'
10 | 3 | 'шуруп'
11 | 3 | 'гайка'
12 | 3 | 'дсп'
13 | 3 | 'двп'
14 | 3 | 'лампа'

Алгоритм следующий:
Из первой таблицы выбираются поочерёдно строки с сортировкой от минимального price к максимальному. Далее выбираются строки стоящие выше по price и смотрится пересечение по 2-ой таблице до первого минимального совпадения (например по 2 пунктам). Если нашли совпадение, то нижестоящий прикрепляется к вышестояещему, а дальше пересечение ищется уже для вышестоящего.

В данном случае будет сперва выбрана строка id_t=2 (у неё наименьший price).Вторым этапом выбирается строка с большим price, это будет id_t=3. Смотрим пересечения по part_table, в данном случае пересечения "дсп" и "лампа", мы прикрепляем дочерний к вышестоящему и дальше смотрим пересечения для вышестоящего.
1 | '' | 198
2 | '2' | 50
3 | 'main' | 167
Выбираем вышестоящий по price - это будет id_t=1, смотрим пересечения по part_table и находим "шуруп" и "гайка", поэтому мы их объединяем, теперь главный - id_t=1.
1 | 'main' | 198
2 | '1' | 50
3 | '1' | 167
Ищем для id_t=1 вышестоящих, но их уже нет, поэтому ставим статус группы - обработано.
1 | 'main_done' | 198
2 | '1' | 50
3 | '1' | 167

Постарался разжевать свои мысли, код тоже прикрепляю, но проблема в том, что при наличии 9к ключей в главной таблице и ~90к в дочерней, всё это жуётся очень долго (жевало пару суток). Каким образом лучше перестроить данные и запросы, чтобы это работало гораздо шустрее?

Запросы:
авторSELECT * FROM main_table WHERE id_t!=".$top['id_t']." and price>=".$top['price']." ORDER BY price, id_t desc

SELECT count(*) FROM part_table as table1, part_table as table2 WHERE table1.id_t=".$top['id_t']." and table2.id_t=".$pod_top['id_t']." and table2.part=table1.part

php код:

авторfunction union_parent($top)
{
global $msconnect;
//выборка в цикле оставшихся строк, выше по price
$pod_top3 = mysql_query("SELECT * FROM main_table WHERE (status='".$main_id."' OR id_t=".$main_id.") and id_t!=".$top['id_t']." and `parent`!='".$top['id_t']."' and price>=".$top['price']." ORDER BY price, id_t desc", $msconnect);
while($pod_top=mysql_fetch_array($pod_top3))
{
//выбираем совпадения
$pod_data=mysql_query("SELECT count(*) FROM part_table as table1, part_table as table2 WHERE table1.id_t=".$top['id_t']." and table2.id_t=".$pod_top['id_t']." and table2.part=table1.part", $msconnect);
$pod_dat=mysql_fetch_array($pod_data);
//если есть совпадения
if($pod_dat[0]>2)
{
if($pod_top['parent']=='main_done'){
//если совпадение с вышестоящим, но который был обработан и глава группы
mysql_query("update main_table set `parent`='".$pod_top['id_t']."' WHERE id_t=".$top['id_t']." or `parent`='".$top['id_t']."'", $msconnect);
}elseif($pod_top['parent']==''){
//если совпадение с вышестоящим, который не был обработан
mysql_query("update main_table set `parent`='".$pod_top['id_t']."' WHERE id_t=".$top['id_t']." or `parent`='".$top['id_t']."'", $msconnect);
mysql_query("update main_table set `parent`='main' WHERE id_t=".$pod_top['id_t'], $msconnect);
return union_parent($pod_top);
}else{
//если совпадение с вышестоящим, который был обработан и он в группе, но не её глава
mysql_query("update main_table set `parent`='".$pod_top['parent']."' WHERE id_t=".$top['id_t']." or `parent`='".$top['id_t']."'", $msconnect);
}
return true;
}
}
//если никого не нашли, то ставим его в гордом одиночестве
mysql_query("update main_table set `parent`='main_done' WHERE id_t=".$top['id_t'], $msconnect);
}

//выбираем в цикле строки
$do=true;
while($do){
$top3 = mysql_query("SELECT * FROM main_table WHERE `parent`='' or `parent`='main' ORDER BY price, id_t desc limit 0,1", $msconnect);
if(mysql_num_rows($top3)>0){
$top=mysql_fetch_array($top3);
union_parent($top);
}else
$do=false;
}
...
Рейтинг: 0 / 0
Правильная группировка по пересечениям
    #38320680
Вот честно - раз пять перечитал и ничего не понял... :(
...
Рейтинг: 0 / 0
Правильная группировка по пересечениям
    #38320808
ZubeQ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый Э - ЭхВот честно - раз пять перечитал и ничего не понял... :(

Значит я плохо донёс мысль, какие вопросы возникли при чтении? Я постараюсь всё разжевать.
...
Рейтинг: 0 / 0
Правильная группировка по пересечениям
    #38320838
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZubeQкакие вопросы возникли при чтении?
Вопрос один - читал ли ты Как правильно задавать вопросы - Описывайте цель, а не отдельный шаг ... а если читал - почему не следуешь совету?
...
Рейтинг: 0 / 0
Правильная группировка по пересечениям
    #38323409
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZubeQ,

Похоже на типичный BOM

http://en.wikipedia.org/wiki/Bill_of_materials
...
Рейтинг: 0 / 0
Правильная группировка по пересечениям
    #38323432
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZubeQ,

SELECT * FROM main_table WHERE id_t!=

Сослепу не заметил сразу. Эта часть за микроскопическим исключением эквипенисуальна запросу вида

SELECT * FROM main_table

Доведем эксперимент до чистоты. $id = 0

Таких id не бывает, следовательно вы получите ВСЮ таблицу взад как будто никакого условия не было в помине. $id = 1; Всю таблицу за исключением 1 записи. Если запрос еще и умножает таблицы - то немудрено двое суток жевать теорию несуществования.

ЗЫ По моим наблюдением в этой рубрике 90 процентов оффтопика который в тему в рубрике проектирование БД, или как она там, где рамочки рисуют.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Правильная группировка по пересечениям
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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