[英]Optimize Subselect Search query
在我的MYSQL數據庫中,我有多個這樣的表:
reference
:
------------------------------
| id | title | subtitle |
| 1 | Test | Just a test |
| 2 | Another | Second |
| 3 | Last | Third |
------------------------------
author
:
-----------------------------
| id | firstname | lastname |
| 1 | Peter | Pan |
| 2 | Foo | Bar |
| 3 | Mr. | Handsome |
| 4 | Steve | Jobs |
-----------------------------
keyword
:
----------------
| id | keyword |
| 1 | boring |
| 1 | lame |
----------------
reference_author_mm
:
---------------------------
| uid_local | uid_foreign |
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 2 |
| 2 | 4 |
| 3 | 1 |
| 3 | 2 |
| 3 | 4 |
---------------------------
所有表都與references
表有一個n:m
關系表。 有一個查詢我想SELECT
所有引用並按作者名稱或關鍵字等過濾/排序 。所以我想要的輸出是這樣的:
按標題搜索的用戶 :
------------------------------------------------------------------------------
| id | title | subtitle | authors | keywords |
| 1 | Test | Just a test | Peter Pan, Foo Bar | boring |
| 2 | Another | Second | Peter Pan, Foo Bar, Steve Jobs | boring, lame |
| 3 | Last | Third | Peter Pan, Foo Bar, Steve Jobs | boring, lame |
-------------------------------------------------------------------------------
此刻我有一個非常長的構造,不太有效:
SELECT r.* , Authors.author AS authors, Keywords.keyword AS keywords
FROM references AS r
LEFT OUTER JOIN (
SELECT r.pid AS pid,
GROUP_CONCAT(CONCAT_WS(\' \', CONCAT(p.lastname, \',\'), p.prefix, p.firstname) SEPARATOR \'; \') AS author
FROM reference AS r
LEFT JOIN reference_author_mm r2p ON r2p.uid_local = r.uid
LEFT JOIN author p ON p.uid = r2p.uid_foreign
GROUP BY r.pid
) Authors ON r.pid = Authors.pid
對於references
每個n:m
關系,此LEFT OUTER JOIN
語句存在多次。 查詢這些表的最簡單方法是什么。 請記住,我需要例如作者的ODER BY
或搜索引用的關鍵字。
我試過的新查詢:
SELECT r.*,
GROUP_CONCAT(CONCAT_WS(\' \', CONCAT(a.lastname, \',\'), a.prefix, a.firstname) SEPARATOR \'; \') AS authors,
GROUP_CONCAT(CONCAT_WS(\' \', k.name)) AS keywords,
GROUP_CONCAT(CONCAT_WS(\' \', c.name)) AS categories,
GROUP_CONCAT(CONCAT_WS(\' \', p.name)) AS publishers
FROM reference AS r
LEFT OUTER JOIN (
SELECT * FROM reference_author_mm AS rha
INNER JOIN author AS a ON a.uid = rha.uid_foreign
) AS a ON a.uid_local = r.uid
LEFT OUTER JOIN (
SELECT * FROM reference_keyword_mm AS rhk
INNER JOIN keywords AS k ON k.uid = rhk.uid_foreign
) AS k ON k.uid_local = r.uid
我試圖根據您在問題中指定的表格結構盡可能清楚地查詢我的查詢(不是我在查詢中看到的)。 您可能需要更改一些字段/表名稱。
您可以在這里查看查詢結果: SQLFiddle演示
SELECT
r.id
,r.title
,r.subtitle
,ra.authors
,rk.keyworks
FROM
reference r
LEFT JOIN
(SELECT
r.id
,GROUP_CONCAT(CONCAT(a.firstname, ' ', a.lastname) ORDER BY CONCAT(a.firstname, ' ', a.lastname) SEPARATOR ', ') as authors
FROM
reference r
LEFT JOIN reference_author_mm r2a
ON r.id = r2a.uid_local
LEFT JOIN author a
ON a.id = r2a.uid_foreign
GROUP BY
r.id) ra
ON ra.id = r.id
LEFT JOIN
(SELECT
r.id
,GROUP_CONCAT(k.keyword ORDER BY k.keyword SEPARATOR ', ') as keyworks
FROM
reference r
LEFT JOIN reference_keyword_mm r2k
ON r.id = r2k.uid_local
LEFT JOIN keyword k
ON k.id = r2k.uid_foreign
GROUP BY
r.id) rk
ON rk.id = r.id
ORDER BY
r.id
如果您需要按姓氏訂購作者姓名,只需將CONCAT(a.firstname, ' ', a.lastname)
更改為CONCAT(a.lastname, ' ', a.firstname)
如果您有任何問題,請隨時更新我的sqlfiddle演示中的表結構,並給我一個注釋,解釋您面臨的問題並給我舉例。
也許?
SELECT r.*,
GROUP_CONCAT(CONCAT_WS(\' \', CONCAT(a.lastname, \',\'), a.prefix, a.firstname) SEPARATOR \'; \')) AS author,
GROUP_CONCAT(CONCAT_WS(\' \', k.keywords) AS keywords
FROM references AS r
LEFT OUTER JOIN (SELECT * FROM references_has_authors AS rha INNER JOIN authors AS a ON a.id = rha.authors_id) AS a ON a.references_id = r.id
LEFT OUTER JOIN (SELECT * FROM references_has_keywords AS rhk INNER JOIN keywords AS k ON k.id = rhk.references_id) AS k ON k.references_id = r.id
GROUP BY r.id;
作為最后的努力,也許在應用程序中做?
SELECT dt1.id,dt1.title,dt1.subtitle,dt1.author_name,dt2.keyword_name
FROM ( SELECT r.id,r.title,r.subtitle,GROUP_CONCAT(CONCAT(a.firstname,' ',a.lastname)) author_name
FROM `reference` r
LEFT JOIN `reference_author_mm` mm ON (r.id = mm.uid_local)
LEFT JOIN `author` a ON (mm.uid_foreign = a.id)
GROUP BY 1,2,3
)dt1
JOIN( SELECT r.id,r.title,r.subtitle,GROUP_CONCAT(keyword) keyword_name
FROM reference r
LEFT JOIN `reference_keyword_mm` km ON (km.uid_local = r.id)
LEFT JOIN `keywords` k ON (k.id = km.uid_foreign)
GROUP BY 1,2,3
)dt2 ON (dt1.id = dt2.id);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.