Sql server 如何对字符串中的数据求和
有表格:Sql server 如何对字符串中的数据求和,sql-server,sql-server-2008,tsql,Sql Server,Sql Server 2008,Tsql,有表格: id name 1 A1=7|A5=1|A10=5|A20=12|A50=8 2 A1=10|A5=2|A10=10|A20=14|A50=4 3 A1=3|A5=3|A10=5|A20=12|A50=8 . . 想要所有A1,A5,A10,A20,A50的总和吗 回答必须是: A1=20|A5=6|A10=20|A20=38|A50=20 如何做到这一点?我也对更改表设计的意见投了赞成票,但有些情况下,有些人无法做到这一点。这是这个案例的解决方案,并不难。当需要处理
id name
1 A1=7|A5=1|A10=5|A20=12|A50=8
2 A1=10|A5=2|A10=10|A20=14|A50=4
3 A1=3|A5=3|A10=5|A20=12|A50=8
.
.
想要所有A1,A5,A10,A20,A50的总和吗
回答必须是:
A1=20|A5=6|A10=20|A20=38|A50=20
如何做到这一点?我也对更改表设计的意见投了赞成票,但有些情况下,有些人无法做到这一点。这是这个案例的解决方案,并不难。当需要处理XML列中的格式化字符串时,我们像往常一样调用XML寻求帮助
-- Prepare data for solution testing
DECLARE @srctable TABLE (
id INT,
name VARCHAR(999),
namexml XML
)
INSERT INTO @srctable
SELECT id, name, namexml FROM ( VALUES
(1, 'A1=7|A5=1|A10=5|A20=12|A50=8', null),
(2, 'A1=10|A5=2|A10=10|A20=14|A50=4', null),
(3, 'A1=3|A5=3|A10=5|A20=12|A50=8', null)
) v (id, name, namexml)
-- Transform source formatted string to XML string
UPDATE @srctable
SET namexml = CAST('<row><data ' + REPLACE(REPLACE(name, '|', '"/><data '), '=', '="') + '"/></row>' AS XML)
-- Final select from XML data
SELECT SUM(x.data.value('(@A1)[1]', 'INT')) AS SUMA1,
SUM(x.data.value('(@A5)[1]', 'INT')) AS SUMA5,
SUM(x.data.value('(@A10)[1]', 'INT')) AS SUMA10,
SUM(x.data.value('(@A20)[1]', 'INT')) AS SUMA20,
SUM(x.data.value('(@A50)[1]', 'INT')) AS SUMA50
FROM @srctable AS t
CROSS APPLY t.namexml.nodes('/row/data') x (data)
您需要以任何方式格式化生成的字符串。不带xml的变体:
--------------------------------------------------------------------------------
-- Prepare data for solution testing
DECLARE @srctable TABLE ( id INT
, NAME VARCHAR(999) )
INSERT INTO @srctable
VALUES ( 1, 'A1=7|A5=1|A10=5|A20=12|A50=8' )
, ( 2, 'A1=10|A5=2|A10=10|A20=14|A50=4' )
, ( 3, 'A1=3|A5=3|A10=5|A20=12|A50=8' )
--------------------------------------------------------------------------------
-- prepare temp table for using in split string
DECLARE @Tally TABLE ( N INT )
DECLARE @i AS INT = 1
WHILE @i != 1000
BEGIN
INSERT INTO @Tally ( N )
VALUES ( @i )
SET @i = @i + 1
END
--------------------------------------------------------------------------------
--final query
;WITH cte AS
(
SELECT id,
(CASE WHEN CHARINDEX('|', S.string) > 0
THEN left(S.string, CHARINDEX('|', S.string) - 1)
ELSE string END ) NAME
FROM @srctable AS E
INNER JOIN @Tally AS T ON SUBSTRING('|' + NAME, T.N, 1) = '|'
AND T.N <= LEN(NAME)
CROSS APPLY (SELECT String = (CASE WHEN T.N = 1
THEN LEFT(E.NAME, CHARINDEX('|', E.NAME) - 1)
ELSE SUBSTRING(E.NAME, T.N, 1000) END )
) AS S
)
SELECT LEFT(NAME, CHARINDEX('=', NAME) - 1) AS NAME,
SUM(convert(float,RIGHT(NAME, CHARINDEX('=', REVERSE(NAME)) - 1))) AS Value
FROM cte
GROUP BY LEFT(NAME, CHARINDEX('=', NAME) - 1)
这将是非常困难的。你最好换张桌子。不要在一列中存储多个值!好的,谢谢,我会改变设计