sql - 多个连接列上的多个 STRING_AGG 导致聚合膨胀

标签 sql sql-server

我的 MSSQL 服务器中有一张表,我们称之为 blogPost .我还有两个标签表,让我们称它们为 fooTagbarTag .标签表用于标记 blogPost结构相同的表。

blogPost

| postId | title               |        body |
+--------+---------------------+-------------+
| 1      | The life on a query | lorem ipsum |
+--------+---------------------+-------------+

fooTag and barTag

| postId | tagName      |
+--------+--------------+
| 1      | sql          |
| 1      | query        |
| 1      | select-query |
+--------+--------------+


我想在一行中获得一篇博文及其所有标签,然后 STRING_AGG()感觉适合进行这样的查询:

SELECT blogPost.*, STRING_AGG(fooTag.tagName, ';') as [fooTags], STRING_AGG(barTag.tagName, ';') as [barTags]
FROM blogPost
LEFT JOIN fooTag ON blogPost.postId = fooTag.postId
LEFT JOIN barTag ON blogPost.postId = barTag.postId
WHERE postId = 1
GROUP BY blogPost.postId, title, body

进行此查询时,我希望得到结果
| postId | title               |        body | fooTags                 | barTags                 |
+--------+---------------------+-------------+-------------------------+-------------------------+
| 1      | The life on a query | lorem ipsum | sql;query;select-query | sql;query;select-query |
+--------+---------------------+-------------+-------------------------+-------------------------+

但是我得到了这个结果,而不是在重复条形标签(即最后选择的 STRING_AGG)的地方。
| postId | title               |        body | fooTags                 | barTags                                       |
+--------+---------------------+-------------+-------------------------+-----------------------------------------------+
| 1      | The life on a query | lorem ipsum | sql;query;select-query; | sql;sql;sql;query;query;query;select-query;select-query;select-query |
+--------+---------------------+-------------+-------------------------+-----------------------------------------------+

推杆 barTags SELECT 语句中的最后一个使得 barTags获取重复项而不是 fooTags .创建的重复数量似乎与第一个 STRING_AGG 中聚合在一起的行列数量有关。结果列,所以如果 fooTags有 5 行要聚合在一起,每行将有 5 个副本 barTagbarTags结果中的列。

我如何在没有重复的情况下获得我想要的结果?

最佳答案

您的问题是由 fooTags 中的每一行引起的创建那么多行 barTagsJOIN ,因此重复。您可以通过执行 STRING_AGG 来解决此问题。在 footagsbartags之前的表 JOIN对他们:

SELECT blogPost.*, f.tags as [fooTags], b.tags as [barTags]
FROM blogPost
LEFT JOIN (SELECT postId, STRING_AGG(tagName, ';') AS tags
           FROM fooTag
           GROUP BY postId) f ON blogPost.postId = f.postId
LEFT JOIN (SELECT postId, STRING_AGG(tagName, ';') AS tags
           FROM barTag
           GROUP BY postId) b ON blogPost.postId = b.postId
WHERE postId = 1

关于sql - 多个连接列上的多个 STRING_AGG 导致聚合膨胀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58184691/

相关文章:

mysql - 循环遍历mysql子查询结果

mysql - 在我的数据库中搜索匹配/包含某些整个关键字的记录

java - 从 SQL Exception 对象获取引发异常的字段和表名称

SQL逐月检查ID状态变化

sql - 使用 BCP 查询输出获取列名

sql - 选择一行而不是另一行

Mysql 随机排序特色产品,但按日期对正常产品进行排序

sql-server - 无效的对象名称 'CHANGETABLE'

html - 如何基于 Perl 脚本创建网站?

sql - 根据日期选择最近的记录