背景介绍
在实际的数据处理中,我们需要对数据进行分组统计,而数据库中的分组统计通常是基于某一列或几列的值进行分组并计算统计值。MSSQL中利用符号分列可以轻松实现这一需求。
符号分列的概念
符号分列是指按某个符号或字符串将一列数据拆分成多列数据,通常用于处理复杂数据结构或从网站抓取数据进行分析等场景。
示例
下面我们以一个示例来说明符号分列的具体实现。
假设我们有一张名为ad_data
的表,其中有一列叫做keywords
,它的值形如:男装,衬衫,职业装
等,表示这个广告标签对应了三个关键词男装
、衬衫
、职业装
。
现在我们想按照每个广告标签中的关键词进行分组统计,即统计每个关键词出现的次数。这个需求可以通过符号分列来实现。
符号分列的具体实现
实现符号分列有多种方法,这里我们介绍三种方法:
方法一:使用PARSENAME函数
PARSENAME函数通常用于处理类似IP地址这种有规律的字符串,它将字符串按照指定分隔符分列,返回指定位置(从右向左数)的子字符串。
对于本例,我们可以利用PARSENAME函数将keywords
列的值按照逗号分隔成多个子字符串,代码如下:
SELECT PARSENAME(REPLACE(keywords,',','.'),3) AS keyword1,
PARSENAME(REPLACE(keywords,',','.'),2) AS keyword2,
PARSENAME(REPLACE(keywords,',','.'),1) AS keyword3
FROM ad_data
该代码将字符串中的逗号替换成点(.RTER)后调用PARSENAME函数,从右到左返回第1、2、3个子字符串,得到如下结果:
keyword1 | keyword2 | keyword3 |
---|---|---|
职业装 | 衬衫 | 男装 |
女装 | 雪纺衫 | 裙子 |
接着我们可以使用UNPIVOT函数将这些列转换成行,并用COUNT函数进行统计:
SELECT keyword,COUNT(*) AS count
FROM (
SELECT PARSENAME(REPLACE(keywords,',','.'),3) AS keyword1,
PARSENAME(REPLACE(keywords,',','.'),2) AS keyword2,
PARSENAME(REPLACE(keywords,',','.'),1) AS keyword3
FROM ad_data
) AS a
UNPIVOT(
keyword FOR keywords IN ([keyword1],[keyword2],[keyword3])
) AS b
GROUP BY keyword
这个代码将三个子字符串转换成三列,并使用UNPIVOT函数将列转换成行,然后按照关键词进行分组统计,得到如下结果:
keyword | count |
---|---|
职业装 | 1 |
衬衫 | 1 |
男装 | 1 |
女装 | 1 |
雪纺衫 | 1 |
裙子 | 1 |
方法二:使用XML函数
XML函数可以将一列数据转换成XML格式,然后用XPath表达式取出XML中的指定节点值。对于本例,我们可以使用XML函数将keywords
列的值转换成XML格式,代码如下:
SELECT CAST(''+REPLACE(keywords,',','')+'' AS XML)
FROM ad_data
这个代码将字符串中的逗号替换成</a><a>
,然后在字符串前后加上<a>
和</a>
,得到如下XML:
<a>男装</a><a>衬衫</a><a>职业装</a>
接着,我们可以使用XPath表达式value('(/a)[1]','nvarchar(max)')
取出第1个节点的值,得到男装
;使用value('(/a)[2]','nvarchar(max)')
取出第2个节点的值,得到衬衫
,以此类推。
将这些XPath表达式放到SELECT子句中,我们可以得到如下代码:
SELECT x.value('(/a)[1]','nvarchar(max)') AS keyword1,
x.value('(/a)[2]','nvarchar(max)') AS keyword2,
x.value('(/a)[3]','nvarchar(max)') AS keyword3
FROM (
SELECT CAST(''+REPLACE(keywords,',','')+'' AS XML) AS xml_data
FROM ad_data
) AS a
CROSS APPLY xml_data.nodes('/a') t(x)
这个代码首先将keywords
列的值转换成XML格式,然后使用CROSS APPLY将XML中的节点作为行输出,并根据XPath表达式取出节点值,得到如下结果:
keyword1 | keyword2 | keyword3 |
---|---|---|
男装 | 衬衫 | 职业装 |
女装 | 雪纺衫 | 裙子 |
最后,我们可以使用UNPIVOT函数和COUNT函数,按照关键词进行分组统计,得到如下代码:
SELECT keyword,COUNT(*) AS count
FROM (
SELECT x.value('(/a)[1]','nvarchar(max)') AS keyword1,
x.value('(/a)[2]','nvarchar(max)') AS keyword2,
x.value('(/a)[3]','nvarchar(max)') AS keyword3
FROM (
SELECT CAST(''+REPLACE(keywords,',','')+'' AS XML) AS xml_data
FROM ad_data
) AS a
CROSS APPLY xml_data.nodes('/a') t(x)
) AS c
UNPIVOT(
keyword FOR keywords IN ([keyword1],[keyword2],[keyword3])
) AS d
GROUP BY keyword
这个代码将三个节点的值转换成三列,并使用UNPIVOT函数将列转换成行,然后按照关键词进行分组统计,得到如下结果:
keyword | count |
---|---|
职业装 | 1 |
衬衫 | 1 |
男装 | 1 |
女装 | 1 |
雪纺衫 | 1 |
裙子 | 1 |
方法三:使用STRING_SPLIT函数
STRING_SPLIT函数是SQL Server 2016及以上版本新增的函数,可以将一列字符串按照指定分隔符分列成多行数据,返回一个表。
对于本例,我们可以使用STRING_SPLIT函数将keywords
列的值按照逗号分隔成多个关键词,代码如下:
SELECT keyword
FROM ad_data
CROSS APPLY STRING_SPLIT(keywords,',')
这个代码将keywords
列的值按照逗号分隔成多个行,并使用CROSS APPLY将这多个行作为输出行,并命名为keyword
,得到如下结果:
keyword |
---|
男装 |
衬衫 |
职业装 |
女装 |
雪纺衫 |
裙子 |
然后,我们可以使用GROUP BY和COUNT函数进行分组统计,得到如下代码:
SELECT keyword,COUNT(*) AS count
FROM ad_data
CROSS APPLY STRING_SPLIT(keywords,',')
GROUP BY keyword
这个代码先使用STRING_SPLIT函数将keywords
列的值按照逗号分隔成多个关键词,然后按照关键词进行分组统计,得到如下结果:
keyword | count |
---|---|
职业装 | 1 |
衬衫 | 1 |
男装 | 1 |
女装 | 1 |
雪纺衫 | 1 |
裙子 | 1 |
总结
本文介绍了MSSQL中符号分列的概念和多种实现方法,并以一个关键词统计的示例进行了说明。通过对MSSQL符号分列的了解和灵活应用,我们可以轻松实现对复杂数据结构的处理和分组统计。