SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 29.10.2010 19:30:15

Avtoritet
Участник
Зарегистрирован: 29.10.2010
Сообщений: 3

Запрос для получения чисел для rowspan при выводе таблиц

Выдуманный упрощенный пример (пример чуть похож на http://sqlinfo.ru/forum/viewtopic.php?id=3259):

tableA - fields: ida (INT) и еще больше 30 шт. (среди них INT, DATETIME, VARCHAR (!!!), ENUM);
tableB - fields: idb (INT) и еще больше 30 шт. (tableA -> tableB - один ко многим (причем одной записи с tableA соответствует много записей (строк) с tableB (от одной до бесконечности)));
tableC - fields: idc (INT) и еще 3шт. (tableB -> tableC - аналогично);
tableD - fields: idd (INT) и еще 3шт. (tableC -> tableD - аналогично).
Все таблицы типа MyISAM.
Выполняется немножко сокращен запрос (так как используются еще вкладываемые запросы (там где одному запросу всегда соответствует единственная запись из другой таблицы)):


SELECT *
FROM tableA AS a
LEFT JOIN tableB AS b ON a.ida=b.id_a
LEFT JOIN tableC AS c ON b.idb=c.id_b
LEFT JOIN tableD AS d ON c.idc=d.id_c
WHERE a.field<1 AND b.field<2 AND b.field>3 AND b.field LIKE '%test%'
ORDER BY ...;
 

Пример-результат:

ida|...|<--~30шт.-->|...| idb|...|<--~30шт.-->|...|idc|...|<--~3шт.-->|...|idd|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...|  1|...|<--~3шт.-->|...|346|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...|  1|...|<--~3шт.-->|...|347|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...|  1|...|<--~3шт.-->|...|348|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...|  1|...|<--~3шт.-->|...|349|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...| 10|...|<--~3шт.-->|...|433|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...| 10|...|<--~3шт.-->|...|434|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...| 10|...|<--~3шт.-->|...|435|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|3000|...|<--~30шт.-->|...| 10|...|<--~3шт.-->|...|436|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|4000|...|<--~30шт.-->|...|  5|...|<--~3шт.-->|...|636|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|4000|...|<--~30шт.-->|...|  5|...|<--~3шт.-->|...|637|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|4000|...|<--~30шт.-->|...|  5|...|<--~3шт.-->|...|638|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|4000|...|<--~30шт.-->|...|  5|...|<--~3шт.-->|...|993|...|<--~3шт.-->|...|
123|...|<--~30шт.-->|...|4000|...|<--~30шт.-->|...|  5|...|<--~3шт.-->|...|994|...|<--~3шт.-->|...|
999|...|<--~30шт.-->|...|5003|...|<--~30шт.-->|...|  8|...|<--~3шт.-->|...| 96|...|<--~3шт.-->|...|
999|...|<--~30шт.-->|...|5003|...|<--~30шт.-->|...|  8|...|<--~3шт.-->|...| 97|...|<--~3шт.-->|...|
999|...|<--~30шт.-->|...|5003|...|<--~30шт.-->|...|  8|...|<--~3шт.-->|...| 98|...|<--~3шт.-->|...|
999|...|<--~30шт.-->|...|5003|...|<--~30шт.-->|...|  8|...|<--~3шт.-->|...| 99|...|<--~3шт.-->|...|
999|...|<--~30шт.-->|...|5003|...|<--~30шт.-->|...|  8|...|<--~3шт.-->|...|100|...|<--~3шт.-->|...|
 

1) А хочется получить:

ida|...|<--~30шт.-->|...|nab| idb|...|<-30шт.->|...|nbc|idc|...|<-3шт.->|...|ncd|idd|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|3000|...|<-30шт.->|...|  2|  1|...|<-3шт.->|...|  4|346|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|3000|...|<-30шт.->|...|  2|  1|...|<-3шт.->|...|  4|347|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|3000|...|<-30шт.->|...|  2|  1|...|<-3шт.->|...|  4|348|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|3000|...|<-30шт.->|...|  2|  1|...|<-3шт.->|...|  4|349|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|3000|...|<-30шт.->|...|  2| 10|...|<-3шт.->|...|  4|433|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|3000|...|<-30шт.->|...|  2| 10|...|<-3шт.->|...|  4|434|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|3000|...|<-30шт.->|...|  2| 10|...|<-3шт.->|...|  4|435|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|3000|...|<-30шт.->|...|  2| 10|...|<-3шт.->|...|  4|436|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|4000|...|<-30шт.->|...|  1|  6|...|<-3шт.->|...|  5|636|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|4000|...|<-30шт.->|...|  1|  6|...|<-3шт.->|...|  5|637|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|4000|...|<-30шт.->|...|  1|  6|...|<-3шт.->|...|  5|638|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|4000|...|<-30шт.->|...|  1|  6|...|<-3шт.->|...|  5|993|...|<-3шт.->|...|
123|...|<--~30шт.-->|...|  2|4000|...|<-30шт.->|...|  1|  6|...|<-3шт.->|...|  5|994|...|<-3шт.->|...|
999|...|<--~30шт.-->|...|  1|5003|...|<-30шт.->|...|  1|  8|...|<-3шт.->|...|  5| 96|...|<-3шт.->|...|
999|...|<--~30шт.-->|...|  1|5003|...|<-30шт.->|...|  1|  8|...|<-3шт.->|...|  5| 97|...|<-3шт.->|...|
999|...|<--~30шт.-->|...|  1|5003|...|<-30шт.->|...|  1|  8|...|<-3шт.->|...|  5| 98|...|<-3шт.->|...|
999|...|<--~30шт.-->|...|  1|5003|...|<-30шт.->|...|  1|  8|...|<-3шт.->|...|  5| 99|...|<-3шт.->|...|
999|...|<--~30шт.-->|...|  1|5003|...|<-30шт.->|...|  1|  8|...|<-3шт.->|...|  5|100|...|<-3шт.->|...|
 

Тоисть расставить числа nab (одна запись с tableA сколько связывает запесей с tableB), nbc(аналогично), ncd (аналогично). Однако за счет этих чисел растет избыточность данных (но не значительно).
2) Но наверно не реально сделать JOIN и при этом расставить числа (nab, nbc, ncd). Тогда надо дополнительный запрос с результатом:

ida|nab| idb|nbc|idc|ncd
123|  2|3000|  2|  1|  4
123|  2|3000|  2| 10|  4
123|  2|4000|  1|  6|  5
999|  1|5003|  1|  8|  5
 

Но тогда будет тяжело наложыть две таблицы при выводе данных (конечною таблицу с результатом и таблицу с числами) чтобы конечный результат был без избыточности данных и нужен дополнительный запрос, а при большых таблицах это критично.

А тепер представте как все усложняется и геометрически растет избыточность если использовать еще tableE,  tableF ... Это трудно представить, но алгоритм один и тот же.

Много усилий нужно для описания задачи, но еще больше для ее решения. Но на форуме действительно профессиональные ответы. Заранее спасибо.

Неактивен

 

#2 29.10.2010 21:00:54

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

Re: Запрос для получения чисел для rowspan при выводе таблиц

Брр, если уж пишете вымышленные запросы — пишите короткие smile Я правильно
понимаю, что Ваша задачка такая:

Есть таблицы A (id), B (id, id_a), C(id, id_B), и нужно построить для каждой строки
из а соответствующее количество строк из B и С? Если да — то как-то так:

SELECT A.id, COUNT(B.id) AS nab
FROM A JOIN B ON A.id = B.id_a
GROUP BY 1;

SELECT A.id, B.id, COUNT(C.id) AS nbc
FROM A JOIN B ON A.id = B.id_a JOIN C ON B.id = C.id_b
GROUP BY 1, 2;

И так далее. Одним запросом, скорее всего, не получится: формулировка
задачи очень расплывчатая: не понятно, какое число выводить для nab,
например, когда есть таблица C.

Неактивен

 

#3 01.11.2010 11:00:06

Avtoritet
Участник
Зарегистрирован: 29.10.2010
Сообщений: 3

Re: Запрос для получения чисел для rowspan при выводе таблиц

paulus написал:

Есть таблицы A (id), B (id, id_a), C(id, id_B), и нужно построить для каждой строки
из а соответствующее количество строк из B и С?

Первая часть вопроса.
Да, верно. А точнее A (idа), B (idb, id_a), C(idc, id_b) ... .
Вторая часть вопроса.
Напомнили эту деталь. Для таблицы A одним числом не обойдешься. Постараюсь поэкспериментировать аналогичным запросами. Хотя пробовал аналогичным единственным запросом все это сделат. Но не получилось.

Просто хотел сконцентрировать внимание на то, что не могу найти оптимальное решение уже не говоря об идеальном. Легко представить, что такая тривиальная задача требует большое количество ресурса (количество запросов, которые достаточно долго будут выполняться при больших количествах таблиц и данных в таблицах (как полей (до 30 шт), так и записей (до 100 тыс. шт.))). Хотя при получении чисел достаточно primary key. Поднял аналогичную тему http://sqlinfo.ru/forum/viewtopic.php?id=3349

Отредактированно Avtoritet (01.11.2010 11:16:43)

Неактивен

 

#4 01.11.2010 15:38:48

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

Re: Запрос для получения чисел для rowspan при выводе таблиц

Давайте всё-таки в одном треде. Из того: если делать отдельными запросами (так, как
в моём примере), то избыточности данных нету.

Неактивен

 

Board footer

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