【问题标题】:Return json in a sql query which is multiple related items在包含多个相关项的 sql 查询中返回 json
【发布时间】:2018-11-18 18:59:08
【问题描述】:

我有一个 web 应用程序,它显示项目列表。

每个项目可以有一个或多个标签。

项目(ID,名称)

标签(ID,名称)

ItemTag(Id, ItemId, TagId)

如果只显示单个项目,则很容易获取项目,然后是标签并在 UI 中显示它们。

但是,当显示可能显示 100 个项目的项目网格时,我想避免必须执行 101 次访问数据库 - 一次获取项目列表,然后为每个集合往返一次数据库每个项目的标签。

我能想到的最好的方法是进行基本查询,然后使用结果构建第二个查询,使用 Id 返回一个长标签列表,然后我将其匹配到各个项目。

有没有更好的方法来做到这一点?例如,如果标签列表可以转换为 json 并在原始查询中作为字符串返回,那么在客户端我可以将其转换回对象并适当地显示它们。但是我不知道怎么写这样的查询。

【问题讨论】:

    标签: sql sql-server sql-server-2016


    【解决方案1】:

    注意:此问题最初标记为 SQL Server 2012。

    您正在寻找字符串聚合——或类似的东西。在 SQL Server 2012+ 中,最好的方法可能是这个 XML 方法,它以逗号分隔的字符串返回标签:

    SELECT i.*,
           STUFF( (SELECT ',' + t.name
                   FROM tags t JOIN
                        ItemTags it
                        ON it.TagID = t.ID
                   WHERE i.ID = it.ItemID
                   ORDER BY t.name
                   FOR XML PATH ('')
                  ), 1, 1, ''
                ) as tags
    WHERE i.Created >= '2018-01-01' and
          i.Created < '2018-02-01';
    

    【讨论】:

      【解决方案2】:

      然后可以在标签上使用您为选择项目提出的任何逻辑:

      --suppose this returns 100 items
      SELECT * FROM Items WHERE Created BETWEEN '2018-01-01' and '2018-02-01'
      
      --select th tags from the items
      SELECT t.* 
      FROM Items i 
      INNER JOIN ItemTags it ON i.ID = it.ItemID
      INNER JOIN Tags t ON it.TagID = t.ID
      WHERE i.Created BETWEEN '2018-01-01' and '2018-02-01'
      

      相同的谓词选择相同的100个项目,数据库通过ItemTags连接到Tags,并返回所有的标签数据。如果你想知道哪个标签数据和哪个项目一起,记得选择它

      【讨论】:

        【解决方案3】:

        使用 Sql Server 2016+,您可以使用 FOR JSON AUTO 返回 json。

        SELECT i.Name,
        (Select t.Name From ItemTags it join Tags t on it.TagId = t.Id Where it.ItemId = i.Id for json auto) as Tags
                from Items i
                where i.Id = 2390
        

        结果:

        【讨论】:

        • 问题标记为 sql-server-2012 ?
        • @CaiusJard,我本来以为我用的是2012,结果我弄错了。我已经更新了问题。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-01
        • 1970-01-01
        • 2022-07-27
        • 1970-01-01
        • 1970-01-01
        • 2021-09-07
        • 1970-01-01
        相关资源
        最近更新 更多