Mysql Помогите правильно составить запрос select из select

simbatron

Новичок
Есть три таблицы:

Код:
select * from jobs;
+--------+----------+------------------+-------------+-------------+--------------+--------+------------+----------+
| num_dt | num_sort | status_dt        | exchange_dt | name_dt     | group_obj_id | obj_id | date_dt    | time_dt  |
+--------+----------+------------------+-------------+-------------+--------------+--------+------------+----------+
|      2 |        1 | работает         |           0 | delete_site |            2 |      4 | 2016-09-14 | 01:10:30 |
+--------+----------+------------------+-------------+-------------+--------------+--------+------------+----------+

Код:
select * from group_obj;
+--------+----------------+----------+
| num_dt | name_dt        | table_dt |
+--------+----------------+----------+
|      1 | Сервера        | servers  |
|      2 | Домены         | domains  |
|      3 | Темы           | thems    |
+--------+----------------+----------+

Код:
select * from domains;
+--------+------------+-----------+
| num_dt | name_dt    | server_id |
+--------+------------+-----------+
|      4 | ramfish.ru |        13 |
|      5 | site-1.ru  |        14 |
+--------+------------+-----------+

Мне нужно выбрать сайт ramfish.ru из таблицы domains в подзапросе.
Основной запрос идет в таблицу jobs, потом по полю из этой таблицы group_obj_id в подзапросе получаем поле table_dt (у которого значение domains) и это значение domains послужит значением таблицы для подзапроса который вернет уже поле name_dt (у которого значение ramfish.ru)

Вот я сделал запрос:
select SQL_CALC_FOUND_ROWS num_dt as num_line, (select name_dt from (select table_dt from group_obj where num_dt=t.group_obj_id limit 1) as t1 where num_dt=t.obj_id limit 1) as obj_dt from jobs as t order by num_dt LIMIT 0, 100
но он не работает, выдает Column not found: 1054 Unknown column 't.group_obj_id' in 'where clause''

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

Дальше ты можешь сделать логичный вывод о том, что динамически использовать в запросе можно только данные, и соответствующим образом перестроить структуру таблиц.
 
@simbatron,
если твои три таблицы сервера, домены, темы можно свести к единой структуре, то
можно реализовать через http://dev.mysql.com/doc/refman/5.7/en/create-view.html
select 1 as group_obj, num_dt as id, name_sr as name from servers union select 2 ,num_dt as id, name_dt from domains union select 2,num_dt as id, name_th from themes
обзовём такую въюшку например view_name

тогда запрос можно строить по объединению
select * from jobs j ,view_name v where j.group_obj_id = v.group_obj and j.obj_id=v.id
 
@Фанат, логичнее, но это если не очень много рефакторинга другого кода и разработка ведется одним человеком.
 
Вообще мне не хочется в одну таблицу собирать (я понимаю что так можно) и домены и сервера и тематики и ... что там еще будет добавляться, там везде разная информация хранится, и вообще все в одну таблицу валить из за того что запрос не получается сделать мне не хочется.
Пробую сделать хранимую функцию:
Код:
DELIMITER $$
CREATE
    FUNCTION `baza`.`object`(group_obj_id INT, obj_id INT) RETURNS VARCHAR(100)
    BEGIN
    DECLARE result VARCHAR(100);
    DECLARE obj_table VARCHAR(100);
    DECLARE query_string VARCHAR(300);
    SELECT table_dt INTO obj_table FROM group_obj WHERE num_dt=group_obj_id;
    SET @query_string := CONCAT('SELECT name_dt INTO result FROM ', obj_table, ' WHERE num_dt=obj_id');
    PREPARE dinamic_query FROM @query_string;
    EXECUTE dinamic_query;
    DEALLOCATE PREPARE dinamic_query;
    RETURN(result);
    END$$
DELIMITER ;
чтоб потом её просто использовать в запросе, но опять же динамические запросы не разрешает делать: "Dynamic SQL is not allowed in stored function or trigger"
 
Да-да. Не хочется строить дом из кирпича потому что в деревянном пол проваливается.
 
Ну вообще в данном случае задача решается left join-нами на все три таблицы и case-ом.

Если хочется с неограниченным числом таблиц и на лету, можно в N запросов (где N = число таблиц + 1), см. реализацию polymorphic relations в Eloquent ORM. В случае, если поля совпадают, можно и в 2 запроса, но во втором будет адский union all N-1 раз.
 
Ну в общем здесь классическая проблема "EAV или другие извращения".
Так что да, возможно, что решение @antson не такое уж кривое и при небольшом размере таблиц вполне прокатит.
 
Ну, да, как-то так. При небольшом размере таблиц и малой вероятности появления четвертой-пятой-шестой я бы, наверное, лефт-джойнами сделал.

Вьюх в mysql я боюсь с тех пор, когда напоролся на баг с игнорированием use/force index в оных, причем explain врал. Хотя его, вроде, исправили давно. Но осадочек остался.

Пробую сделать хранимую функцию:
В хранимке ты не сделаешь ничего такого, чего нельзя сделать php-кодом.
 
ой ну сколько там записей будет ;)
темплаты 5-10 тыс
домены менее 10 тыс
серверы до 10 штук
 
В хранимке ты не сделаешь ничего такого, чего нельзя сделать php-кодом.
Это понятно что можно запросов из php наделать сколько хочешь, но тогда как к этим данным применять order by, where, ...

если твои три таблицы сервера, домены, темы можно свести к единой структуре, то
можно реализовать через http://dev.mysql.com/doc/refman/5.7/en/create-view.html
select 1 as group_obj, num_dt as id, name_sr as name from servers union select 2 ,num_dt as id, name_dt from domains union select 2,num_dt as id, name_th from themes
обзовём такую въюшку например view_name

тогда запрос можно строить по объединению
select * from jobs j ,view_name v where j.group_obj_id = v.group_obj and j.obj_id=v.id
Изучаю эту тему, раньше не пользовался, только мне думается там будут ограничения похожие на "Dynamic SQL is not allowed in stored function or trigger"
Я же сделал процедуру с динамическим запросом, с процедурой все срабатывает, потом сделал функцию с вызовом этой процедуры и эта функция естественно не заработала из за "Dynamic SQL is not allowed in stored function or trigger"

Я даже начал смотреть в сторону postgresql но пока только интересуюсь, там вроде побольше пространства для маневра.
 
Еще такой вариант возможен: Компиляция и установка определяемых пользователем функций
Можно на С написать свою функцию которая делает запрос в mysql и применять её в запросе, но такую функцию нужно компилировать для каждой системы отдельно, это тоже серьезное ограничение, потом в другом месте применять такую функцию не удобно будет.
 
Делай вью уже и не кочевряжься.
С точки зрения производительности это конечно жесть, ну так у тебя и не хайлоад
 
В postgresql с этим все ровно так же. Во всех РСУБД одинаково. Сначала парсится SQL-запрос в абстрактное дерево (где уже четко заданы имена таблиц и полей), потом по ним строится план выполнения запроса (опять же для конкретных таблиц, полей и условий), потом этот план выполняется.
 
Сверху