我在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.
答案 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