簡體   English   中英

優化子選擇搜索查詢

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM