Han*_*mer 5 sql sql-server group-by aggregate-functions
我的 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 |
+--------+--------------+
Run Code Online (Sandbox Code Playgroud)
我想在一行中获取一篇博文及其所有标签,因此STRING_AGG()
适合进行如下查询:
blogPost
| postId | title | body |
+--------+---------------------+-------------+
| 1 | The life on a query | lorem ipsum |
+--------+---------------------+-------------+
fooTag and barTag
| postId | tagName |
+--------+--------------+
| 1 | sql |
| 1 | query |
| 1 | select-query |
+--------+--------------+
Run Code Online (Sandbox Code Playgroud)
进行此查询时,我希望得到结果
| postId | title | body | fooTags | barTags |
+--------+---------------------+-------------+-------------------------+-------------------------+
| 1 | The life on a query | lorem ipsum | sql;query;select-query | sql;query;select-query |
+--------+---------------------+-------------+-------------------------+-------------------------+
Run Code Online (Sandbox Code Playgroud)
但我得到的结果是条形标签(即最后选择的 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 |
+--------+---------------------+-------------+-------------------------+-----------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
将barTags
最后放在 SELECT 语句中可以barTags
获取重复项而不是fooTags
. 创建的重复项数量似乎与第一个结果列中聚合在一起的行列数量相关STRING_AGG
,因此如果有 5 行聚合在一起,则结果列中的fooTags
每行将有 5 个重复项。barTag
barTags
我怎样才能得到我想要的结果而不重复?
您的问题是由在 中fooTags
创建那么多行的每一行引起的,因此是重复的。您可以通过在和表之前执行 来解决此问题:barTags
JOIN
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
Run Code Online (Sandbox Code Playgroud)
您可以像这样简化查询:
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
Run Code Online (Sandbox Code Playgroud)
不需要 GROUP BY,在您的情况下,这将是一个昂贵的操作。
归档时间: |
|
查看次数: |
7972 次 |
最近记录: |