如何在管道值之后对数字求和

时间:2015-06-24 15:02:16

标签: sql split sum substring

我在SQL中有一个列,其中包含由管道分隔的值。在每个值之后,有一个我想要聚合的数字,但我不了解最佳方法。

列如下所示:

{Carrots:1}|{Bananas:2}|{Watermelon:1}

我做了类似的事情:

SELECT 
    NOME, PRICE,
    SUM(CASE WHEN VEGETABLE LIKE '%Carrots%' THEN 1 ELSE 0 END) as Carrots,
    SUM(CASE WHEN VEGETABLE LIKE '%Banana%'  THEN 1 ELSE 0 END) as Banana,
    SUM(CASE WHEN VEGETABLE LIKE '%Watermelon%' THEN 1 ELSE 0 END) as Watermelon
FROM 
    Market
GROUP BY 
    NOME, PRICE

但这样只会增加价值,

column1的输出为:1 Carrot , 1 Banana, 1 Watermelon;

但我想添加例如2(在:之后,它是一个数字2)。

那就像是:1 Carrot, 2 Banana, 1 Watermelon.

3 个答案:

答案 0 :(得分:0)

这会有效,虽然我同意jpw的回应,但我已经享受了这种快乐。使用不会改变其格式的客户发送的数据。

SELECT
Name, Price,
CAST(SUM(CASE WHEN [Vegetable] LIKE '%Carrots%' THEN SUBSTRING([Vegetable],CHARINDEX('Carrots:',[Vegetable])+8,1) ELSE 0 END) AS VARCHAR) + ' Carrot , ' +
CAST(SUM(CASE WHEN [Vegetable] LIKE '%Banana%'  THEN SUBSTRING([Vegetable],CHARINDEX('Bananas:',[Vegetable])+8,1) ELSE 0 END) AS VARCHAR) + ' Banana , ' +
CAST(SUM(CASE WHEN [Vegetable] LIKE '%Watermellon%' THEN SUBSTRING([Vegetable],CHARINDEX('Watermellon:',[Vegetable])+12,1) ELSE 0 END) AS VARCHAR) + ' Watermellon' as Column1 
FROM Market
GROUP BY name, price

输出

1 Carrot , 2 Banana , 1 Watermellon

答案 1 :(得分:0)

请找到以下代码,以便为您的目的服务。您可以将此代码转换为2个函数。一个将字符串转换为数字字符串,然后将另一个字符串转换为每个数字

Declare @String varchar(4000) = '{Carrots:1}|{Bananas:2}|{Watermellon:1}';            
Declare @NumOnly varchar(100) = '%[^0-9]%';
Declare @Sum int = 0;
Declare @Cnt int = 1;

--Convert String to a numeric String
WHILE PatIndex(@NumOnly, @String) > 0
BEGIN
    SET @String = Stuff(@String, PatIndex(@NumOnly, @String), 1, '');
END   
SELECT @String;

--add up each character (digit) in the numeric string
WHILE @Cnt <= LEN(@String)
BEGIN
    SET @Sum = @Sum + CONVERT(INT, SUBSTRING(@String,@Cnt,1));
    SET @Cnt = @Cnt + 1;
END     
SELECT @Sum;

答案 2 :(得分:0)

您可以使用SUBSTRING()功能来实现这一目标,不过您最好根据评论中的建议更改模型。但是,这并不总是可行的,所以如果你必须使用这种格式,你可以使用以下内容:

SELECT 
    NOME, 
    PRICE,
    SUM(CASE WHEN VEGETABLE  LIKE '%Carrots%' THEN SUBSTRING(VEGETABLE , CHARINDEX(':', VEGETABLE , CHARINDEX('Carrots', VEGETABLE ))+1, 1) ELSE 0 END) as Carrots,
    SUM(CASE WHEN VEGETABLE  LIKE '%Banana%'  THEN SUBSTRING(VEGETABLE , CHARINDEX(':', VEGETABLE , CHARINDEX('Banana', VEGETABLE ))+1, 1) ELSE 0 END) as Banana,
    SUM(CASE WHEN VEGETABLE  LIKE '%Watermelon%' THEN SUBSTRING(VEGETABLE , CHARINDEX(':', VEGETABLE , CHARINDEX('Watermelon', VEGETABLE ))+1, 1) ELSE 0 END) as Watermelon
FROM 
    Market
GROUP BY 
    NOME, PRICE
编辑:作为一个完美的论据,为什么这种模型是一个坏主意,我上面的解决方案没有考虑到多位数字。我已经提出了一个解决方案(下面),它可以弥补这一点,但是我将原始代码作为一个案例研究,为什么字符串操作并不好玩。

DECLARE @VEGETABLE VARCHAR(100) = '{Carrots:1000}|{Bananas:20}|{Watermelon:1}'

SELECT 
    SUM(CASE 
        WHEN @VEGETABLE  LIKE '%Carrots%' 
        THEN SUBSTRING(
            @VEGETABLE , 
            CHARINDEX(':', @VEGETABLE , CHARINDEX('Carrots', @VEGETABLE ))+1, 
            CHARINDEX('}', @VEGETABLE , CHARINDEX('Carrots', @VEGETABLE )) - (CHARINDEX(':', @VEGETABLE , CHARINDEX('Carrots', @VEGETABLE ))+1)) 
        ELSE 0 END) as Carrots,
    SUM(CASE 
        WHEN @VEGETABLE  LIKE '%Banana%' 
        THEN SUBSTRING(
            @VEGETABLE , 
            CHARINDEX(':', @VEGETABLE , CHARINDEX('Banana', @VEGETABLE ))+1, 
            CHARINDEX('}', @VEGETABLE , CHARINDEX('Banana', @VEGETABLE )) - (CHARINDEX(':', @VEGETABLE , CHARINDEX('Banana', @VEGETABLE ))+1)) 
        ELSE 0 END) as Bananas,
    SUM(CASE 
        WHEN @VEGETABLE  LIKE '%Watermelon%' 
        THEN SUBSTRING(
            @VEGETABLE , 
            CHARINDEX(':', @VEGETABLE , CHARINDEX('Watermelon', @VEGETABLE ))+1, 
            CHARINDEX('}', @VEGETABLE , CHARINDEX('Watermelon', @VEGETABLE )) - (CHARINDEX(':', @VEGETABLE , CHARINDEX('Watermelon', @VEGETABLE ))+1)) 
        ELSE 0 END) as Carrots