SQL - 如何通过 link 查询多个 table ./ associative table

SQL - How to query multiple tables via a link ./ associative table

我在查询多个 SQL table 并正确连接结果时遇到问题。我有 3 个 table 1) 一个包含文章的主 table,2) 一个包含主题标签列表的 table,以及 3) 一个将标签链接到的关联 table文章。
我试图构建以下查询: - 查询一个主table - 对于每个结果,在第三个 table 中获取相关标签(由关联 table 链接) - 没有标签关联的地方仍然包括主要 table 的结果(我尝试了各种连接)

我花了几天的时间尝试并可能阅读了 30 多篇关于 stackexchange 的帖子,但仍然有一个问题,我无法同时 return 所有结果并获得与记录中的记录正确关联的标签主要table。我试过左/外/内关节,但它们都会 return 所有记录的所有标签,而不是正确关联它们。

这是第一个示例,其中的结果是正确的,但所有可用的标签都已添加到每条记录中。 [结果正确但标签错误1

这是第二个示例,其中标签与结果正确关联,但没有标签的结果未 returned [标签正确但不包含没有标签的结果2

这是一个SQL代码(对应于第二个屏幕截图)。

SELECT 
    Ar.Title, 
    Ar.Analysis_CategoryLevelOne_Name AS MainCategory, 
    Ar.Analysis_CategoryLevelTwo_Name AS SubCategory, 
    null AS GenericName, 
    Ar.Summary,
    Ar.Author AS Source,
    'Article' AS ContentType, 
    MATCH (Ar.Title, Summary, Content)
    AGAINST ('a*' IN BOOLEAN MODE) AS Relevance,
    GROUP_CONCAT(Su.Name) AS Tags
    FROM `conArticles` AS Ar,
    `refSubjectTags` AS Su,
    `linkArticlesToSubjectTags` AS Link
    WHERE MATCH (Title, Summary, Content)
    AGAINST ('a*' IN BOOLEAN MODE) AND CurrentOrBackup = 'Current'
    AND Ar.Articles_id = Link.linkArticlesToSubjectTags_Articles_Id
    AND Link.linkArticlesToSubjectTags_SubjectTags_Id = Su.SubjectTags_Id
    GROUP BY Ar.Articles_Id
    ORDER BY 'Relevance' 'DESC';

对于如何获得所有结果以及与主 table 中的记录正确关联的标签,我将不胜感激。

更新:在尝试两个左连接的建议之后,我修改了以下查询。虽然我现在从主 table 获得了所有正确的结果,但所有标签都与每个结果相关联,这不是我想要的(输出显示在所附的第一张图片中)。关于 table 结构,它对应于 Nosyara 提出的那个结构,即我有一个 intermediate/associative table,它只包含主要标签和标签 table 之间的 id 对( Articles_Id <=> SubjectTags_Id )。我添加了关联 table [关联 table 3

的屏幕截图
SELECT 
    Ar.Title, 
    Ar.Analysis_CategoryLevelOne_Name AS MainCategory, 
    Ar.Analysis_CategoryLevelTwo_Name AS SubCategory, 
    null AS GenericName, 
    Ar.Summary,
    Ar.Author AS Source,
    'Article' AS ContentType, 
    MATCH (Ar.Title, Summary, Content)
    AGAINST ('a*' IN BOOLEAN MODE) AS Relevance,    
    GROUP_CONCAT(Su.Name) AS Tags
    FROM    `refSubjectTags` AS Su,
    `conArticles` AS Ar
    LEFT JOIN linkArticlesToSubjectTags Link
    ON Ar.Articles_id = Link.linkArticlesToSubjectTags_Articles_Id
    LEFT JOIN refSubjectTags Su2
    ON Link.linkArticlesToSubjectTags_SubjectTags_Id = Su2.SubjectTags_Id
    WHERE MATCH (Title, Summary, Content)
    AGAINST ('a*' IN BOOLEAN MODE) 
    GROUP BY Ar.Articles_Id
    ORDER BY 'Relevance' 'DESC';

注意:这已经解决了。请参阅答案下方的正确代码。

您需要 2 个左联接。

这里我创建了简化的模式

CREATE TABLE IF NOT EXISTS `main` ( `title` varchar(200));
CREATE TABLE IF NOT EXISTS `tags` ( id int(10), `Name` varchar(200));
CREATE TABLE IF NOT EXISTS `links` ( `title` varchar(200),  `tag` int(10));

INSERT INTO main VALUES ('Foo'),  ('Bar'),  ('Baz');
INSERT INTO tags VALUES (1, 'tag1'), (2, 'tag2'), (3, 'tag3'), (4, 'tag4');
INSERT INTO links VALUES ('Foo', 1), ('Foo', 2), ('Bar', 3),  ('Bar', 4),  ('Hello', 5), ('Foo', 6);

这是SQL:

select ar.title, group_concat(t.name) as tags 
from main ar 
left join links lnk on ar.title=lnk.title 
left join tags t on lnk.tag = t.id
group by title

输出:

title    tags
-----    -----
Bar      tag3,tag4
Baz      (null)
Foo      tag1,tag2

http://sqlfiddle.com/#!9/a14ef4/1

解决方案是 1) 添加两个左连接,2) 将 SubjectTags table 的声明移动到第二个 LEFT JOIN,3) 将 linkArticlesToSubjectTags table 的声明移动到第一个 LEFT JOIN,以及 4) 将 table ids 关联从 WHERE CLAUSE 移动到 LEFT JOINS。

下面是正确的代码:

SELECT 
    Ar.Title, 
    Ar.Analysis_CategoryLevelOne_Name AS MainCategory, 
    Ar.Analysis_CategoryLevelTwo_Name AS SubCategory, 
    null AS GenericName, 
    Ar.Summary,
    Ar.Author AS Source,
    'Article' AS ContentType, 
    MATCH (Ar.Title, Summary, Content)
    AGAINST ('employ*' IN BOOLEAN MODE) AS Relevance,   
    GROUP_CONCAT(Su.Name) AS Tags
    FROM `conArticles` AS Ar
    LEFT JOIN linkArticlesToSubjectTags Link
    ON Ar.Articles_id = Link.linkArticlesToSubjectTags_Articles_Id
    LEFT JOIN refSubjectTags Su
    ON Link.linkArticlesToSubjectTags_SubjectTags_Id = Su.SubjectTags_Id
    WHERE MATCH (Title, Summary, Content)
    AGAINST ('employ*' IN BOOLEAN MODE) 
    GROUP BY Ar.Articles_Id
    ORDER BY 'Relevance' 'DESC';

以下为原错误代码:

SELECT 
    Ar.Title, 
    Ar.Analysis_CategoryLevelOne_Name AS MainCategory, 
    Ar.Analysis_CategoryLevelTwo_Name AS SubCategory, 
    null AS GenericName, 
    Ar.Summary,
    Ar.Author AS Source,
    'Article' AS ContentType, 
    GROUP_CONCAT(Su.Name) AS Tags
    FROM    
    `refSubjectTags` Su, **[ Move to 2nd LEFT JOIN ]**
    `conArticles` Ar,
    `linkArticlesToSubjectTags` Link **[ Move to 1st LEFT JOIN ]**
    **[ Add the 2 LEFT JOINS ]**
    WHERE MATCH (Title, Summary, Content)
    AGAINST ('a*' IN BOOLEAN MODE) 
    AND Ar.Articles_id = Link.linkArticlesToSubjectTags_Articles_Id
    AND Link.linkArticlesToSubjectTags_SubjectTags_Id = Su.SubjectTags_Id
    **[ The 2 lines above needs to be moved to the 2 LEFT JOINS ]**
    GROUP BY Ar.Articles_Id
    ORDER BY 'Relevance' 'DESC';