Я хочу извлечь результаты из таблиц EAV (сущность-атрибут-значение) или, в частности, таблиц метаданных сущности (например, wordpress wp_posts
и wp_postmeta
), как "красиво отформатированную реляционную таблицу", чтобы сделать некоторую сортировку и / или фильтрацию .
Я нашел несколько примеров того, как отформатировать результаты в запросе (в отличие от написания двух запросов и объединения результатов в коде), но я хотел бы знать «наиболее эффективный» метод для этого, особенно для больших наборов результатов.
И когда я говорю «самый эффективный», я имею в виду что-то вроде следующих сценариев:
Получить все сущности с фамилией, такие как XYZ
Возвращение списка сущностей, отсортированных по дню рождения
например. включите это:
** ENTITY **
-----------------------
ID | NAME | whatever
-----------------------
1 | bob | etc
2 | jane | etc
3 | tom | etc
** META **
------------------------------------
ID | EntityID | KEY | VALUE
------------------------------------
1 | 1 | first name | Bob
2 | 1 | last name | Bobson
3 | 1 | birthday | 1983-10-10
. | 2 | first name | Jane
. | 2 | last name | Janesdotter
. | 2 | birthday | 1983-08-10
. | 3 | first name | Tom
. | 3 | last name | Tomson
. | 3 | birthday | 1980-08-10
в это:
** RESULTS **
-----------------------------------------------
EID | NAME | first name | last name | birthday
-----------------------------------------------
1 | bob | Bob | Bobson | 1983-10-10
2 | jane | Jane | Janesdotter | 1983-08-10
3 | tom | Tom | Tomson | 1980-08-10
чтобы я мог сортировать или фильтровать по любому из мета-полей.
Я нашел несколько предложений здесь , но я не могу найти ни одного обсуждения, которое работает лучше.
Опции
- GROUP_CONCAT :
SELECT e.*, GROUP_CONCAT( CONCAT_WS('||', m.KEY, m.VALUE) ORDER BY m.KEY SEPARATOR ';;' )
FROM `ENTITY` e JOIN `META` m ON e.ID = m.EntityID
- Multi-Join :
SELECT e.*, m1.VALUE as 'first name', m2.VALUE as 'last name', m3.VALUE as 'birthday'
FROM `ENTITY` e
LEFT JOIN `META` m1
ON e.ID = m1.EntityID AND m1.meta_key = 'first name'
LEFT JOIN `META` m2
ON e.ID = m2.EntityID AND m2.meta_key = 'last name'
LEFT JOIN `META` m3
ON e.ID = m3.EntityID AND m3.meta_key = 'birthday'
- Коалесцентный :
SELECT e.*
, MAX( IF(m.KEY= 'first name', m.VALUE, NULL) ) as 'first name'
, MAX( IF(m.KEY= 'last name', m.VALUE, NULL) ) as 'last name'
, MAX( IF(m.KEY= 'birthday', m.VALUE, NULL) ) as 'birthday'
FROM `ENTITY` e
JOIN `META` m
ON e.ID = m.EntityID
- Код :
SELECT e.* FROM `ENTITY` e WHERE e.ID = {whatever};
в PHP, создайте объект-заполнитель из результата
SELECT m.* FROM `META` m WHERE m.EntityID = {whatever};
в PHP, просматривайте результаты и присоединяйте к объекту сущности как:
$e->{$result->key} = $result->VALUE
Что лучше вообще и для фильтрации / сортировки?
Похожие вопросы:
- Результаты связывания EAV
- Как развернуть сущность MySQL