Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何对字符串中的数据求和_Sql Server_Sql Server 2008_Tsql - Fatal编程技术网

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)

这将是非常困难的。你最好换张桌子。不要在一列中存储多个值!好的,谢谢,我会改变设计