MySQL объединяет таблицы, где имя таблицы является полем другой таблицы
У меня 5 таблиц. Один основной и 4 дополнительных (у них разные столбцы).
- объекты
- obj_mobiles
- obj_tablets
- obj_computers
Вот структура моей основной таблицы (объектов).
ID | тип | имя | так далее...
Поэтому я хочу объединить объекты с другими (obj_mobiles,obj_tablets,...) таблицами, в зависимости от поля типа. Я знаю, что я должен использовать динамический SQL. Но я не могу сделать процедуру. Я думаю, это должно выглядеть примерно так.
SELECT objects.type into @tbl FROM objects;
PREPARE stmnt FROM "SELECT * FROM objects AS object LEFT JOIN @tbl AS info ON object.id = info.obj_id";
EXECUTE stmnt;
DEALLOCATE PREPARE stmnt;
Также псевдокод
SELECT * FROM objects LEFT JOIN [objects.type] ON ...
Кто-нибудь может опубликовать процедуру? Также я хочу, чтобы все строки были не только в 1 строке. Благодарю.
3 ответа
Если вы хотите, чтобы все строки (массовый вывод), а не по одной строке за раз, приведенное ниже должно быть быстрым, и вывод для всех строк будет содержать все столбцы.
Рассмотрим ниже поля таблиц. obj_mobiles - ID | М1 | M2 obj_tablets - ID | T1 | T2 obj_computers - ID | C1 | Объекты C2 - ID | тип | имя | так далее.,
Select objects.*, typestable.*
from (
select ID as oID, "mobile" as otype, M1, M2, NULL T1, NULL T2, NULL C1, NULL C2 from obj_mobiles
union all
select ID as oID, "tablet" as otype, NULL, NULL, T1, T2, NULL, NULL from obj_tablets
union all
select ID as oID, "computer" as otype, NULL, NULL, NULL, NULL, C1, C2 from obj_computers) as typestable
left join objects on typestable.oID = objects.ID and typestable.otype = objects.type;
+------+--------------------+----------+------+----------+------+------+------+------+------+------+
| ID | name | type | ID | type | M1 | M2 | T1 | T2 | C1 | C2 |
+------+--------------------+----------+------+----------+------+------+------+------+------+------+
| 1 | Samsung Galaxy s2 | mobile | 1 | mobile | 1 | Thin | NULL | NULL | NULL | NULL |
| 2 | Samsung Galaxy Tab | tablet | 2 | tablet | NULL | NULL | 0.98 | 10 | NULL | NULL |
| 3 | Dell Inspiron | computer | 3 | computer | NULL | NULL | NULL | NULL | 4.98 | 1000 |
+------+--------------------+----------+------+----------+------+------+------+------+------+------+
Таблица создается как ниже.
mysql> create table objects (ID int, name varchar(50), type varchar (15));
Query OK, 0 rows affected (0.05 sec)
mysql> insert into objects values (1, "Samsung Galaxy s2", "mobile"), (2, "Samsung Galaxy Tab", "tablet"), (3, "Dell Inspiron", "computer");
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> create table obj_mobiles (ID int, M1 int, M2 varchar(10));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into obj_mobiles values (1, 0.98, "Thin");
Query OK, 1 row affected (0.00 sec)
mysql> create table obj_tablets (ID int, T1 float, T2 int(10));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into obj_tablets values (2, 0.98, 10);
Query OK, 1 row affected (0.00 sec)
mysql> create table obj_computers (ID int, C1 float, C2 int(10));
Query OK, 0 rows affected (0.03 sec)
insert into obj_computers values (3, 4.98, 1000);
Кроме того, чтобы подтвердить, что типы данных столбцов совпадают с исходными столбцами, результат сохраняется в таблице, а типы данных проверяются ниже.
create table temp_result as
Select objects.*, typestable.*
from (
select ID as oID, "mobile" as otype, M1, M2, NULL T1, NULL T2, NULL C1, NULL C2 from obj_mobiles
union all
select ID as oID, "tablet" as otype, NULL, NULL, T1, T2, NULL, NULL from obj_tablets
union all
select ID as oID, "computer" as otype, NULL, NULL, NULL, NULL, C1, C2 from obj_computers) as typestable
left join objects on typestable.oID = objects.ID and typestable.otype = objects.type;
mysql> desc temp_result;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| ID | int(11) | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
| type | varchar(15) | YES | | NULL | |
| oID | int(11) | YES | | NULL | |
| otype | varchar(8) | NO | | | |
| M1 | int(11) | YES | | NULL | |
| M2 | varchar(10) | YES | | NULL | |
| T1 | float | YES | | NULL | |
| T2 | int(11) | YES | | NULL | |
| C1 | float | YES | | NULL | |
| C2 | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
11 rows in set (0.00 sec)
Если objects
является родительской таблицей, это означает, что objects
,ID
это уникальный объект. Правильно? Все остальные элементы (мобильные телефоны, планшеты, компьютеры) являются дочерними для объекта, и мобильный телефон и планшет не могут иметь одинаковый идентификатор. Если это так, достаточно использовать этот простой запрос -
SELECT * FROM objects o
LEFT JOIN obj_mobiles m
ON o.id = m.ID
LEFT JOIN obj_tablets t
ON o.id = t.ID
LEFT JOIN obj_computers c
ON o.id = c.ID
Добавьте предложение WHERE к типам фильтров, например: WHERE o.type = 'mobile'.
ИСПОЛЬЗУЙТЕ CONCAT, чтобы создать свое подготовительное заявление. например.
@sql = CONCAT('SELECT * FROM objects AS object LEFT JOIN ', @tbl, ' AS info ON object.id = info.obj_id');
PREPARE stmnt FROM @sql;
...