TSQL GROUP BY字符串的一部分

时间:2012-04-20 07:56:39

标签: tsql sql-server-2005 group-by

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

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',第一个包含1,000和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 /*fere 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

2 个答案:

答案 0 :(得分: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方法

答案 1 :(得分:1)

如果有多个下划线,这个蒙太奇的表达式将从参数的开头到最后的_隔离字符串:

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

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

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

为避免重复此blob,请使用派生表而不是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