0
我有以下表格,有關這個問題:檢索項匹配的標籤,並同時檢索到的各項目走的所有標籤
project
- projectId (PK)
- projectTitle
- projectDescription
- etc..
tag
- tagId
- tagName
- tagDescription
- etc...
project_tag
- projectId (PK/FK -> project.projectId)
- tagId (PK/FK -> tag.tagId)
我實施類似於StackOverflow的具有標籤功能,在那個人能夠查看由一個或多個標籤標記的項目列表(在我的情況下是項目)。 我想要做的是選擇所有項目,至少要標記所有標記給我的查詢,但同時檢索所有與每個單獨項目一起使用的標記。
我現在的工作,但我覺得WHERE IN
子句中的子查詢是非常低效的,因爲這可能會爲每一行執行,是正確的嗎?
SELECT
`project`.*,
GROUP_CONCAT(DISTINCT `tagName` ORDER BY `tagName` SEPARATOR ' ') as `tags`
FROM
`project`
JOIN
`project_tag`
USING (`projectId`)
JOIN
`tag`
USING (`tagId`)
WHERE
`projectId` IN (
SELECT
`projectId`
FROM
`project_tag`
JOIN
`tag`
USING (`tagId`)
WHERE
`tagName` IN ('the', 'tags')
GROUP BY
`projectId`
HAVING
COUNT(DISTINCT `tagName`) = 2 # the amount of tags in the IN clause
)
GROUP BY
`projectId`
有什麼辦法加入就tag
,使得我能夠同時檢索爲JOIN
版項目的所有標籤,而只有JOIN
ING預計,(至少)匹配我喂到所有標籤查詢,而不必使用WHERE IN
子句?
一個例子來說明結果,考慮這些示例項目:
projectId: 1, tags: php, cms, webdevelopment
projectId: 2, tags: php, cms, ajax
projectId: 3, tags: c#, cms, webdevelopment
搜索標籤php
和cms
會產生(這些未格式化爲實際的MySQL查詢的結果,它只是說明相關數據):
projectId: 1, tags: php, cms, webdevelopment
projectId: 2, tags: php, cms, ajax
不只是:
projectId: 1, tags: php, cms
projectId: 2, tags: php, cms
嘿,謝謝你的回答。 '子查詢不相關...';啊,是的,這是有道理的。就在你回答之前,我實際上提出了一個與你所建議的類似的查詢。但是我實際上沒有'tagName'上的索引,所以我現在添加了。該列是一個'VARCHAR(50)'(目前,仍處於開發階段)。你會建議我設置一個索引長度嗎? –
我不會擔心在該索引上設置長度。要進行測試,請記住,如果IN子句中的標記數量大於MySQL可能會忽略該索引的可能標記數量(大約爲10%左右,這在使用有限的測試數據時非常容易發生)。 – Kickstart
好的,謝謝你的寶貴見解。 –