我的MSSQL服务器中有一个表,让我们称它为blogPost。我还有两个标签表,我们称它们为fooTag和barTag。标签表用于标记结构相同的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行要聚合在一起,那么结果中的barTags列中的每个barTag将有5个重复。
如果没有副本,我怎么能得到我想要的结果?
发布于 2019-10-01 12:29:18
您的问题是由fooTags中的每一行在JOIN中创建那么多行barTags引起的,因此出现了重复。您可以通过在STRING_AGG表中执行footags和bartags表中的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发布于 2019-10-01 13:19:07
您可以将查询简化如下:
SELECT blogPost.*, ca1.*, ca2.*
FROM blogPost
OUTER APPLY (
SELECT STRING_AGG(tagName, ';')
FROM fooTag
WHERE blogPost.postId = fooTag.postId
) AS ca1(fooTags)
OUTER APPLY (
SELECT STRING_AGG(tagName, ';')
FROM barTag
WHERE blogPost.postId = barTag.postId
) AS ca2(barTags)
WHERE postId = 1不需要分组,在您的情况下,这将是一个昂贵的操作。
https://stackoverflow.com/questions/58184691
复制相似问题