У меня очень досадная проблема с приложением, в котором я работал по контракту.
Структура базы данных, , которую я не могу изменить из соображений совместимости - беспорядок. Это в основном отношения «многие-ко-многим-многим-многим-к-кому-то-бить-по-твоему-на-столе» . Это выглядит так:
контакт
---------------------------
| contact_id | name | ... |
---------------------------
| 1 | foo | |
---------------------------
metadefinition
-----------------------------
| metadefinition_id | name |
-----------------------------
| 1 | title |
-----------------------------
| 2 | job |
-----------------------------
contact_metadata
----------------------------
| contact_id | metadata_id |
----------------------------
| 1 | 1 |
----------------------------
| 1 | 2 |
----------------------------
метаданные
-------------------------------------------
| metadata_id | metadefinition_id | value |
-------------------------------------------
| 1 | 1 | mrs |
-------------------------------------------
| 2 | 2 | coder |
-------------------------------------------
Итак, для одного контакта я хочу найти все это и получить что-то вроде этого:
-----------------------------------------------------
| contact_id | name | metadata.title | metadata.job |
-----------------------------------------------------
| 1 | foo | mrs | coder |
-----------------------------------------------------
Так что теперь я попробовал. Я могу получить список metadefinition
заранее, это не проблема. Поэтому я строю запрос следующим образом:
SELECT contact.*,m1.value AS `metadata.title` FROM contact
LEFT JOIN contact_metadata ON contact.contact_id = contact_metadata.contact_id
LEFT JOIN metadata m1 ON contact_metadata.metadata_id = m1.metadata_id AND m1.metadefinition_id = 1
GROUP BY contact_id
Это работает для одного metadefinition
, я получаю что-то вроде этого:
--------------------------------------
| contact_id | name | metadata.title |
--------------------------------------
| 1 | foo | mrs |
--------------------------------------
Если я попробую с двумя, однако:
SELECT contact.*,m1.value AS `metadata.title`,m2.value AS `metadata.job` FROM contact
LEFT JOIN contact_metadata ON contact.contact_id = contact_metadata.contact_id
LEFT JOIN metadata m1 ON contact_metadata.metadata_id = m1.metadata_id AND m1.metadefinition_id = 1
LEFT JOIN metadata m2 ON contact_metadata.metadata_id = m2.metadata_id AND m2.metadefinition_id = 2
GROUP BY contact_id
Я получаю:
-----------------------------------------------------
| contact_id | name | metadata.title | metadata.job |
-----------------------------------------------------
| 1 | foo | mrs | NULL |
-----------------------------------------------------
Если я удалю предложение GROUP BY, конечно, я получу:
-----------------------------------------------------
| contact_id | name | metadata.title | metadata.job |
-----------------------------------------------------
| 1 | foo | mrs | NULL |
-----------------------------------------------------
| 1 | foo | NULL | coder |
-----------------------------------------------------
Я открыт для всего, пока время запросов относительно приемлемо (учитывая структуру, если для 100000 записей требуется 10 секунд, это лучше, чем ничего)
Будут ли это временные таблицы, хранимые процедуры, мне все равно, если мне не нужно менять фактическую структуру базы данных.
Поверь мне, когда придет время переделывать, я с удовольствием сниму все это.
Есть ли решение для этого, возможно ли это?
Заранее спасибо.