TSQL GROUP BY字符串的一部分

问题描述 投票:4回答:2

我有一个简单的查询。像这样的东西:

SELECT l.list_name, COUNT(order_id) 
FROM orders o JOIN lists l ON l.order_id=o.order_id 
    WHERE l.list_name LIKE 'orders_1%' or l.list_name LIKE 'orders_2%'
GROUP BY l.list_name

这种情况看起来是这样:整个存储过程正在更新列表表,但是如果有1000个以上的订单,它将把列表分成几部分。

如果我有1200个带有标准的订单或列表'orders_1',那么我的过程将创建两个列表:'orders_1_1''和orders_1_2',第一个具有1000个订单,第二个具有200个订单。

因此,当我运行查询以计算这些订单时,我将得到如下结果:

list_name                  count

orders_1                   100
orders_1_more_than_100_1   1000       
orders_1_more_than_100_2   200
orders_2                   400 
orders_3_1                 1000       
orders_3_2                 1000
orders_3_3                 420  
orders_3_more_than_100_1   1000       
orders_3_more_than_100_2   900
orders_3_more_than_200_1   1000       
orders_3_more_than_200_2   1000
orders_3_more_than_200_3   100      
orders_4                   200
orders_4_more_than_300     200 

我想要获得的结果应如下所示:

list_name                  count

orders_1                   100
orders_1_more_than_100     1200       
orders_2                   400 
orders_3                   2420 
orders_3_more_than_100     1900 
orders_3_more_than_200     2100     
orders_4                   200 
orders_4_more_than_300     200 

这样它将汇总所有以相同开头的列表。

有什么想法吗? :)

这些是我在list_names列中的确切值:

WYS_AUT_PISMO_NR_6
WYS_AUT_PISMO_NR_5_POWYZEJ_240
WYS_AUT_PISMO_NR_5_DO_240
WYS_AUT_PISMO_NR_4_POWYZEJ_240_5
WYS_AUT_PISMO_NR_4_POWYZEJ_240_4
WYS_AUT_PISMO_NR_4_POWYZEJ_240_3
WYS_AUT_PISMO_NR_4_POWYZEJ_240_2
WYS_AUT_PISMO_NR_4_POWYZEJ_240_1
WYS_AUT_PISMO_NR_4_DO_240
WYS_AUT_PISMO_NR_3_POWYZEJ_240
WYS_AUT_PISMO_NR_3_DO_240
WYS_AUT_PISMO_NR_2_POWYZEJ_240
WYS_AUT_PISMO_NR_2_DO_240
WYS_AUT_PISMO_NR_1

我想要像这样对它们进行分组:

WYS_AUT_PISMO_NR_6
WYS_AUT_PISMO_NR_5_POWYZEJ_240
WYS_AUT_PISMO_NR_5_DO_240
WYS_AUT_PISMO_NR_4_POWYZEJ_240 /*here I must group those 5 lists*/
WYS_AUT_PISMO_NR_4_DO_240
WYS_AUT_PISMO_NR_3_POWYZEJ_240
WYS_AUT_PISMO_NR_3_DO_240
WYS_AUT_PISMO_NR_2_POWYZEJ_240
WYS_AUT_PISMO_NR_2_DO_240
WYS_AUT_PISMO_NR_1
tsql sql-server-2005 group-by
2个回答
2
投票
如果下划线有多个,则此怪异的表达式将从参数的开头到最后的_隔离字符串:

select case when len (l.list_name) - len (replace (l.list_name, '_', '')) > 1 then left(l.list_name, len (l.list_name) - charindex('_', reverse(l.list_name))) else l.list_name end

或者,您可以从字符串中删除'orders_',将下划线替换为点,然后将其转换为float,然后将其转换为int以删除小数,然后使用此怪物将其返回到字符串:

select 'orders_' + cast (cast (cast ( replace (substring (@str, 8, 100), '_', '.') as float) as int) as varchar(100))

为了避免重复此斑点,请使用派生表代替lists

SELECT l.TrimmedListName, COUNT(order_id) FROM orders o JOIN ( select lists.*, -- Remove optional list continuation number case when len (list_name) - len (replace (list_name, '_', '')) > 1 then left(list_name, len (list_name) - charindex('_', reverse(list_name))) else list_name end AS TrimmedListName from lists ) l ON l.order_id=o.order_id WHERE (l.list_name LIKE 'orders_1%' or l.list_name LIKE 'orders_2%') GROUP BY l.TrimmedListName


2
投票
尝试类似

select substring(l.list_name, 0, 8), count(order_Id) FROM orders o JOIN lists l ON l.order_id=o.order_id WHERE l.list_name LIKE 'orders_1%' or l.list_name LIKE 'orders_2%' group by substring(l.list_name, 0, 8)

已更新问题的已更新答案:

select newColName, COUNT(order_id) from ( select case when GetSubstringCount(l.list_name, '_', '') > 1 then SUBSTRING(l.list_name, 0, len(l.list_name) - 2) else l.list_name end as NewColName , order_Id FROM orders o JOIN lists l ON l.order_id=o.order_id WHERE l.list_name LIKE 'orders_1%' or l.list_name LIKE 'orders_2%' ) mySubTable group by newColName

您将需要类似This的东西来创建GetSubstringCount方法
© www.soinside.com 2019 - 2024. All rights reserved.