Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.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
TSQL按字符串的一部分分组_Tsql_Sql Server 2005_Group By - Fatal编程技术网

TSQL按字符串的一部分分组

TSQL按字符串的一部分分组,tsql,sql-server-2005,group-by,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 list_name count orders_1

我有一个简单的问题。大概是这样的:

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
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 
这种情况看起来是这样的:一个存储过程正在更新列表表,但是如果有超过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 
我希望得到的结果如下所示:

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
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 
因此,它将对所有以相同开头的列表求和

有什么想法吗?:)

以下是我在“列表名称”列中的确切值:

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
试试像这样的东西

    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

您需要创建GetSubstringCount方法之类的内容

如果有多个下划线,则此异常表达式将隔离从参数开头到最后一个
\uu的字符串:

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_u2;”,用点替换下划线并将其转换为float,然后转换为int以删除小数,然后使用此怪物返回字符串:

select 'orders_' + cast (cast (cast (
        replace (substring (@str, 8, 100), '_', '.') 
        as float) as int) as varchar(100))
为避免重复此blob,请使用派生表而不是
列表

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

我不知道我可以按子字符串分组:)我马上检查:)再编辑一次。如果我的名字列表长度不同怎么办?我会编辑我的问题当然,没问题,尽管我想你只需要把子字符串表达式调大,也许会在字符串中找到第一个下划线,然后取一个长度,下划线位置+1Ok,这更复杂,你会有一个大的讨厌的群体,因为有一秒钟我在想子字符串会解决我的问题,搜索最后一个下划线也不会有任何帮助:/你每天都让我大吃一惊。只要看看你的代码就可以显示你的技能。你真棒!我马上试试:)只有一个问题。如果我有两个列表,比如:orders\u 1\u more\u than\u 100\u 1和orders\u 1\u more\u than\u 100\u 2,你的脚本很好,但如果我只有一个列表:orders\u 4,它会切掉最后两个符号。@Misiu我一定误解了什么,因为对我来说,它保留了“orders\u 4”。你能把列表的确切值公布出来吗?@Misiu我看到了你的初稿。我将使用新的“\u more\u than”值进行检查。@Misiu请您将
>1
更改为
>6
?如果列表中有6个或更少的下划线,这将使列表名称不受影响。