我有一个展览和艺术家数据库。每个展览都与任何数量的艺术家联系在一起,并通过数据透视表加入,如下:
'exhibitions'
+-----+--------------------------+
| id | title |
+-----+--------------------------+
| 358 | A Closed Circuit |
| 360 | Do You Love Me? |
| 361 | Romans |
| 364 | Men in Love |
| 367 | Bien Hoa |
| 369 | Jokes |
| 370 | Speech |
| 373 | Shimabuku's Fish & Chips |
+-----+--------------------------+
'artists'
+-----+-----------------+----------------------+
| id | first_name | last_name |
+-----+-----------------+----------------------+
| 301 | Roman | Schramm |
| 302 | Ben | Schumacher |
| 303 | Hugh | Scott-Douglas |
| 304 | Nina | Beier and Marie Lund |
| 305 | Constant | Dullaart |
| 306 | Brenna | Murphy |
| 307 | Jaako | Pallasvuo |
| 308 | Nicolas | Pelzer |
| 309 | Jon | Rafman |
+-----+-----------------+----------------------+
'associations'
+-------+-------------+------+-------------+------+
| id | a_t | a_id | b_t | b_id |
+-------+-------------+------+-------------+------+
| 21371 | exhibitions | 369 | artists | 301 |
| 21373 | exhibitions | 1842 | artists | 2644 |
| 21379 | exhibitions | 315 | artists | 2644 |
| 27752 | exhibitions | 4015 | artists | 2644 |
| 21848 | exhibitions | 71 | artists | 2650 |
| 34 | artists | 1 | exhibitions | 1 |
| 85 | artists | 5 | exhibitions | 36 |
| 90 | artists | 8 | exhibitions | 38 |
| 97 | artists | 10 | exhibitions | 39 |
| 98 | artists | 54 | exhibitions | 40 |
| 100 | artists | 55 | exhibitions | 42 |
| 102 | artists | 55 | exhibitions | 43 |
| 103 | artists | 301 | exhibitions | 370 |
| 584 | exhibitions | 998 | venues | 22 |
| 1234 | venues | 15 | exhibitions | 370 |
+-------+-------------+------+-------------+------+
'venues'
+------+--------------------+
| id | name |
+------+--------------------+
| 22 | ACME |
| 1116 | Adams and Ollman |
| 510 | Adamski |
| 1077 | Agustina Ferreyra |
| 15 | Air de Paris |
+------+--------------------+
我需要创建一个符合以下条款的搜索:
但是,正如您所看到的,associations
表中有一些交换的条目。有时展览是“A”表,有时它是“B”。此外,它也不是一个简单的数据透视表 - 正如您所看到的,它正在为所有表创建关联。这是我必须使用的,并将其分解为更简洁的数据透视表(表A至B,而不是当前的表A / B / C / D / E至A / B / C / D / E)将需要在别处进行大量重构并且是不可能的。
作为一个例子:艺术家David Leiske的ID为128
,以及双向关联:
mysql> select * from associations where (a_t = 'artists' AND a_id = 126 AND b_t = 'exhibitions') OR (a_t = 'exhibitions' AND b_id = 126 AND b_t = 'artists');
+-------+-------------+------+-------------+------+
| id | a_t | a_id | b_t | b_id |
+-------+-------------+------+-------------+------+
| 10438 | artists | 126 | exhibitions | 458 |
| 10772 | exhibitions | 55 | artists | 126 |
| 27490 | artists | 126 | exhibitions | 3877 |
| 27500 | artists | 126 | exhibitions | 3878 |
| 28435 | artists | 126 | exhibitions | 4378 |
| 28474 | artists | 126 | exhibitions | 4379 |
| 28475 | artists | 126 | exhibitions | 4380 |
+-------+-------------+------+-------------+------+
这两个问题分别给了我需要的东西:
SELECT exhibitions.id as result_id, 'exhibitions' as result_type, exhibitions.title AS result_title, GROUP_CONCAT(CONCAT_WS(' ', artists.first_name, artists.last_name)) AS col_3
FROM exhibitions
LEFT JOIN associations AS associations ON (associations.b_id = exhibitions.id AND b_t = 'exhibitions' AND a_t = 'artists')
LEFT JOIN artists ON (associations.a_id = artists.id AND a_t = 'artists')
WHERE
(artists.id IS NOT NULL)
AND ((CONCAT_WS(' ', artists.first_name, artists.last_name)) RLIKE 'Lieske')
OR (exhibitions.title RLIKE 'Lieske')
GROUP BY exhibitions.id
+-----------+-------------+------------------------------------------------------------+
| result_id | result_type | result_title | col_3 |
+-----------+-------------+------------------------------------------------------------+
| 458 | exhibitions | Deformation Professionelle | David Lieske |
| 3877 | exhibitions | Der africanishe Stuhl von marcel Breuer | David Lieske |
| 3878 | exhibitions | Imerium in Imperio | David Lieske |
| 4378 | exhibitions | A Greater Administration of Lower Interests | David Lieske |
| 4379 | exhibitions | Platitude Normale | David Lieske |
| 4380 | exhibitions | Fantôme Mains Sur | David Lieske |
+-----------+-------------+------------------------------------------------------------+
和
SELECT exhibitions.id as result_id, 'exhibitions' as result_type, exhibitions.title AS result_title, GROUP_CONCAT(CONCAT_WS(' ', artists.first_name, artists.last_name)) AS col_3
FROM exhibitions
LEFT JOIN associations AS associations ON (associations.a_id = exhibitions.id AND a_t = 'exhibitions' AND b_t = 'artists')
LEFT JOIN artists ON (associations.b_id = artists.id AND b_t = 'artists')
WHERE
(artists.id IS NOT NULL)
AND ((CONCAT_WS(' ', artists.first_name, artists.last_name)) RLIKE 'Lieske')
OR (exhibitions.title RLIKE 'Lieske')
GROUP BY exhibitions.id
+-----------+-------------+--------------+--------------+
| result_id | result_type | result_title | col_3 |
+-----------+-------------+--------------+--------------+
| 55 | exhibitions | Adequate | David Lieske |
+-----------+-------------+--------------+--------------+
我可以将两个查询联合成一个 - 这给了我最终的结果。但是,我将动态地构建这个查询 - 这只是一个更全面的搜索的一个(麻烦)部分,如果我能处理这个A:B / B:一种更动态的关系会更容易。
我尝试在连接中添加OR:
SELECT exhibitions.id as result_id, 'exhibitions' as result_type, exhibitions.title AS result_title, GROUP_CONCAT(CONCAT_WS(' ', artists.first_name, artists.last_name)) AS col_3
FROM exhibitions
LEFT JOIN associations AS associations ON (associations.b_id = exhibitions.id AND b_t = 'exhibitions' AND a_t = 'artists')
OR (associations.a_id = exhibitions.id AND a_t='exhibitions' AND b_t='artists')
LEFT JOIN artists ON (associations.a_id = artists.id AND a_t = 'artists')
OR (associations.b_id = artists.id AND b_t = 'artists')
WHERE
(artists.id IS NOT NULL)
AND ((CONCAT_WS(' ', artists.first_name, artists.last_name)) RLIKE 'Lieske')
OR (exhibitions.title RLIKE 'Lieske')
GROUP BY exhibitions.id
但是,我知道我做错了,因为查询需要30秒,而UNION'd查询需要0.07。
我在这里做错了什么?
最后:我如何将venues.name
加入到表中并将其添加到查询中?
示例搜索:
RLIKE 'art|acme'
,预期结果:在标题中art
并且在会场ACME
RLIKE 'davis|paris'
,预期结果:展览包括名字为davis
的艺术家,该作品发生在Air de Paris
(我知道这些会带来所有的OR比赛 - 但是,这篇文章已经足够长了,所以我可以再做一个关于排名结果的人。)