【问题标题】:Tagging: SQL query to return tagged and untagged items标记:用于返回标记和未标记项目的 SQL 查询
【发布时间】:2013-03-01 02:08:38
【问题描述】:

我正在构建一个包含标记的数据库,并使用“毒”模式,其中我有 3 个表:

Items: Item, ItemID, more fields
Tags: TagName, TagID, more fields
TagMap: TagID, ItemID

我正在尝试构建一个查询来列出所有项目及其标签,其中许多项目可能没有标签。我找不到可以同时执行这两种操作的查询。

以下查询按名称获取带有标签的项目,但只会提取具有 标签的项目。

SELECT Items.Item, Tags.Tag
FROM Items INNER JOIN 
(Tags INNER JOIN TagMap ON Tags.ID = TagMap.TagId)
ON Items.ID = TagMap.ItemId;

如果已标记,以下查询会为我获取所有项目及其 TagID,但我似乎无法在单个查询中将这些 TagID 转换为 TagNames 的下一步。

SELECT [Items].Item, [TagMap].TagId
FROM Items LEFT JOIN TagMap ON [Items].ID=TagMap.ItemId;

MSDN 说“外部联接可以嵌套在多表联接中的内部联接中,但内部联接不能嵌套在外部联接中”,但我找不到任何嵌套两个联接的方法抛出错误。据我所知,我需要 LEFT JOIN 才能出现在 Items 上。

我在 Access 中工作以在概念数据库上构建我的证明,因为它已经安装在我的机器上。我可能会在某个时候切换到 SQL Server。

【问题讨论】:

    标签: sql ms-access tagging


    【解决方案1】:

    您已经很接近了 - 只需添加 1 个额外的 LEFT JOIN

    SELECT [Items].Task, [TagMap].TagId, Tags.TagName
    FROM Items 
        LEFT JOIN TagMap ON [Items].ID=TagMap.TaskId
        LEFT JOIN Tags ON TagMap.TagID=Tags.TagID
    

    由于您使用的是 MS Access,因此您需要在联接周围使用括号——这样的内容应该很接近:

    SELECT [Items].Task, [TagMap].TagId, Tags.TagName
    FROM (Items 
        LEFT JOIN TagMap ON [Items].ID=TagMap.TaskId)
        LEFT JOIN Tags ON TagMap.TagID=Tags.TagID
    

    【讨论】:

    • 谢谢!那行得通。如果我可能会问,为什么另一个 LEFT JOIN?对我来说,标签的映射似乎真的必须是一个 INNER JOIN。
    • @alwayssummer -- np,很高兴我能帮上忙。如果记录不存在于 TagMap 和/或 Tags 表中,您将需要使用 LEFT JOIN。这样,您将始终收到 Items.Task 字段,但可能会收到 TagId 和/或 TagName 字段的 NULL 值(如您的示例中所示)。祝你好运!
    猜你喜欢
    • 1970-01-01
    • 2022-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多