我有一个Web应用程序,其中显示项目列表。
每个项目可以具有一个或多个标签。
Item(Id,Name)
标记(ID,名称)
ItemTag(Id,ItemId,TagId)
如果仅显示单个项目,则很容易获得该项目,然后将其标记并显示在UI中。
但是,当显示一个网格项目(可能显示100个项目)时,我要避免去数据库进行101次旅行-一次获取项目列表,然后每组一次去数据库每个项目的标签数量。
我能想到的最好的方法是进行基本查询,然后使用结果使用Ids构建第二个查询,以返回一个长长的Tag列表,然后我将其与各个项目进行匹配。
是否有更好的方法?例如,如果标签列表可以转换为json并在原始查询中以字符串形式返回,那么在客户端上,我可以将其转换为对象并适当地显示它们。但是我不知道如何编写这样的查询。
答案 0 :(得分:0)
然后,您可以在标签上使用用于选择商品的任何逻辑:
--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连接到Tag,并返回所有tag数据。如果您需要知道哪些标签数据与哪个项目一起使用,请记住选择它
答案 1 :(得分:0)
注意:该问题最初被标记为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 :(得分:0)