Mysql Объединение таблицы с самой собой

WBS

Новичок
Есть большая таблица table с полями:
id_obj - ID объекта
id_param - ID параметра
val - значение параметра

Нужно получить результат со строками вида:
id_obj, param1_val, param2_val, param3_val

Вижу три варианта решения.


1. LEFT JOIN с вложенными запросами
Код:
SELECT
  id_obj, R1.val as param1_val, R2.val as param2_val, R3.val as param3_val
FROM
  (SELECT id_obj, val FROM table WHERE id_param=1) R1
  LEFT JOIN (SELECT id_obj, val FROM table WHERE id_param=2) R2 USING (id_obj)
  LEFT JOIN (SELECT id_obj, val FROM table WHERE id_param=3) R3 USING (id_obj)
Работает как надо, но из-за многочисленных вложенных запросов все это выполняется дольше, чем хотелось бы.


2. LEFT JOIN исходных таблиц
Код:
SELECT
  id_obj, R1.val as param1_val, R2.val as param2_val, R3.val as param3_val
FROM
  table R1
  LEFT JOIN table R2 USING (id_obj)
  LEFT JOIN table R3 USING (id_obj)
WHERE
  R1.id_param=1 AND R2.id_param=2 AND R3.id_param=3
Работает быстрее, но не выбирает объекты, для которых некоторые параметры не прописаны в таблице table. Хотя требуется выбрать все объекты и для неизвестных параметров прописать значение NULL (как делает первый вариант запроса).


3. Изменить структуру таблицы (провести денормализацию), чтобы таблица изначально имела структуру "id_obj, param1_val, param2_val, param3_val". Тут очевидные недостатки: избыточность (в базе будут храниться NULL значения) и сложности с обновлением (добавление новых параметров, добавление/изменение значений параметров).


Подскажите, есть ли более удачные варианты решения задачи?
 

artoodetoo

великий и ужасный
Удачность зависит от задачи ))) Тема эта старинная и наывается EAV
https://www.google.ru/search?q=work+with+eav+table

IMHO, если в твоей задаче можно обойтись "вариантом 3", значит это нужно сделать. К костылю EAV прибегают когда набор "полей" меняется со временем.
 
  • Like
Реакции: WBS

fixxxer

К.О.
Партнер клуба
Если параметров мало и они редко меняются, то п.3.
Если много, то либо EAV, либо что-то вроде постгресовского hstore, если есть - в mariadb, например, можно так.
 
  • Like
Реакции: WBS
Сверху