在包含多个相关项的 sql 查询中返回 json
Posted
技术标签:
【中文标题】在包含多个相关项的 sql 查询中返回 json【英文标题】:Return json in a sql query which is multiple related items 【发布时间】:2018-11-18 18:59:08 【问题描述】:我有一个 web 应用程序,它显示项目列表。
每个项目可以有一个或多个标签。
项目(ID,名称)
标签(ID,名称)
ItemTag(Id, ItemId, TagId)
如果只显示单个项目,则很容易获取项目,然后是标签并在 UI 中显示它们。
但是,当显示可能显示 100 个项目的项目网格时,我想避免必须执行 101 次访问数据库 - 一次获取项目列表,然后为每个集合往返一次数据库每个项目的标签。
我能想到的最好的方法是进行基本查询,然后使用结果构建第二个查询,使用 Id 返回一个长标签列表,然后我将其匹配到各个项目。
有没有更好的方法来做到这一点?例如,如果标签列表可以转换为 json 并在原始查询中作为字符串返回,那么在客户端我可以将其转换回对象并适当地显示它们。但是我不知道怎么写这样的查询。
【问题讨论】:
【参考方案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,结果我弄错了。我已经更新了问题。以上是关于在包含多个相关项的 sql 查询中返回 json的主要内容,如果未能解决你的问题,请参考以下文章