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
解决方案是 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';
我在查询多个 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
解决方案是 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';