我有一个数据库,其表格非常简化,如下所示
Column 1 Column 2 (varchar)
Vector 1 23^34^45^65
Vector 2 0^54^10^31
现在我想将第2列的单元格中的数字相加。也就是说,我希望它看起来像这样:
Column 1 Column 2 (varchar)
Vector 1 167
Vector 2 95
我如何在SQL中执行此操作?
答案 0 :(得分:5)
也许你想要这样的东西:
SELECT a.col1, sum_of_values = SUM(d.val)
FROM (VALUES ('Vector 1', '23^34^45^65'), ('Vector 2', '0^54^10^31')) a (col1, col2)
CROSS APPLY (SELECT CONVERT(xml, '<a>' + REPLACE(a.col2, '^', '</a><a>')+'</a>')) AS b(doc)
CROSS APPLY b.doc.nodes('a') c (item)
CROSS APPLY (SELECT c.item.value('.', 'int')) d (val)
GROUP BY a.col1
输出:
col1 sum_of_values
-------- -------------
Vector 1 167
Vector 2 95
说明:
VALUES
子句是您数据的占位符。REPLACE
使用XML标记的插入符号(^
),我们可以使用xml
数据类型上的方法来有效地拆分值。CROSS APPLY
使用nodes()
数据类型的xml
方法,每个项目返回一个新行,并返回包含项目值的xml
列。value('.', 'int')
会将<a>
元素的内部文字转换为int
。GROUP BY
和SUM
汇总了这些结果,并将行数减少回原来的两个。编辑:您可以将拆分移动到自己的功能中。像这样:
CREATE FUNCTION dbo.SplitIntOnCaret (@list varchar(max)) RETURNS TABLE AS RETURN
SELECT Position = ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
, Value = item.value('.', 'int')
FROM (SELECT CONVERT(xml, '<a>' + REPLACE(@list, '^', '</a><a>')+'</a>')) AS a(doc)
CROSS APPLY doc.nodes('a') c (item)
所以你的最终查询可能如下所示:
SELECT l.list_id, sum_of_values = SUM(s.value)
FROM dbo.MyLists l
CROSS APPLY dbo.SplitIntOnCaret(l.list) AS s
GROUP BY l.list_id
答案 1 :(得分:0)
如果您无法更改数据的存储方式,则必须
<label class="item item-input item-floating-label"
ng-class="{'has-errors':{{loginForm.$submitted && loginForm['AccountLoginForm[username]'].$invalid}} || {{loginForm.$submitted && loginForm['AccountLoginForm[username]'].$valid && success.data.login=='err'}},
'no-errors':{{loginForm.$submitted && loginForm['AccountLoginForm[username]'].$valid}} || {{loginForm.$submitted && loginForm['AccountLoginForm[username]'].$valid && success.data.login=='ok'}}">
</label>
计算SUM
。