在我的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 |
---------------------------
所有表都与n:m
表有一个references
关系表。通过一个查询,我想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
此LEFT OUTER JOIN
语句与n:m
的每个references
关系存在多次。查询这些表的最简单方法是什么。请记住,我需要例如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
答案 0 :(得分:1)
我尝试根据您在问题中指定的表格结构尽可能清楚地查询我的查询(而不是我在您的查询中看到的内容)。 您可能需要更改一些字段/表名。
您可以在此处查看查询结果: SQLFiddle demo
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演示中的表格结构,并留下评论,说明您面临的问题并给我举例。
答案 1 :(得分:0)
也许?
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;
作为最后的努力,也许在申请中做什么?
答案 2 :(得分:0)
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);