收集匹配条件的特定值,对连续值进行分组

时间:2011-06-21 16:35:43

标签: tsql group-by

对于令人困惑的标题感到抱歉,我想不出更好的工作方式。

我有一组数据,其中一些值是连续数字

lngDoffID   strProductNumber
876190      20170L
876205      20170L
876206      20170L
876207      20170L
876209      20170L
876210      20170L
876211      20170L
876212      20170L
876215      20170L
876200      20180T
876205      20180T
876206      20180T
876207      20180T
876208      20180T
876209      20180T
876210      20180T
876211      20180T    

我想要一个返回此内容的查询:

strProductNumber    strDoffRange
20170L              876190
20170L              876205-876207
20170L              876209-876212
20170L              876215
20180T              876200
20180T              876205-876211

或者这会更好:

strProductNumber    strDoffRange
20170L              876190, 876205-876207, 876209-876212, 876215
20180T              876200, 876205-876211

2 个答案:

答案 0 :(得分:1)

-- Sample data
;with YourTable(lngDoffID,   strProductNumber) as
(
select 876190,      '20170L' union all
select 876205,      '20170L' union all
select 876206,      '20170L' union all
select 876207,      '20170L' union all
select 876209,      '20170L' union all
select 876210,      '20170L' union all
select 876211,      '20170L' union all
select 876212,      '20170L' union all
select 876215,      '20170L' union all
select 876200,      '20180T' union all
select 876205,      '20180T' union all
select 876206,      '20180T' union all
select 876207,      '20180T' union all
select 876208,      '20180T' union all
select 876209,      '20180T' union all
select 876210,      '20180T' union all
select 876211,      '20180T'
)

-- Your query
select strProductNumber,
       stuff((select ', '+
                     cast(min(lngDoffID) as varchar(10))+
                     case when min(lngDoffID) = max(lngdoffID) 
                          then '' 
                          else '-'+cast(max(lngDoffID) as varchar(10)) 
                     end
              from ( select *,
                            row_number() over(order by strProductNumber, lngDoffID) as rn
                     from YourTable
                   ) as T
              where T.strProductNumber = Y.strProductNumber      
              group by strProductNumber, lngDoffID-rn
              order by strProductNumber, min(lngDoffID)
              for xml path('')), 1, 2, '') as strDoffRange
from YourTable as Y
group by strProductNumber

结果:

strProductNumber strDoffRange
---------------- ---------------------------------------------
20170L           876190, 876205-876207, 876209-876212, 876215
20180T           876200, 876205-876211

答案 1 :(得分:0)

此查询提供您需要的输出


SELECT AD.STRPRODUCTNUMBER,
       WM_CONCAT(AD.JOIN_VAL) AS JOIN_VAL
       FROM 
(SELECT A1.STRPRODUCTNUMBER,
       DECODE(TO_CHAR(A1.LGNDOFFID, '999999'),
              TO_CHAR(A2.LGNDOFFID, '999999'),
              TO_CHAR(A1.LGNDOFFID, '999999'),
              TO_CHAR(A2.LGNDOFFID, '999999') || '-' || TO_CHAR(A1.LGNDOFFID, '999999')) AS JOIN_VAL
  FROM (SELECT A.STRPRODUCTNUMBER, A.LGNDOFFID, ROWNUM AS ROW_NUM
          FROM (SELECT DISTINCT BT.STRPRODUCTNUMBER,
                                BT.LGNDOFFID,
                                DECODE((SELECT DISTINCT BT1.LGNDOFFID
                                         FROM SO_BUFFER_TABLE_5 BT1
                                        WHERE BT1.STRPRODUCTNUMBER =
                                              BT.STRPRODUCTNUMBER
                                          AND (BT1.LGNDOFFID =
                                              BT.LGNDOFFID + 1)),
                                       NULL,
                                       'FALSE',
                                       'TRUE') AS NEXT_VAL_EXIST
                  FROM SO_BUFFER_TABLE_5 BT
                 ORDER BY BT.STRPRODUCTNUMBER) A
         WHERE A.NEXT_VAL_EXIST = 'FALSE') A1,
       (SELECT A.STRPRODUCTNUMBER, A.LGNDOFFID, ROWNUM AS ROW_NUM
          FROM (SELECT DISTINCT BT.STRPRODUCTNUMBER,
                                BT.LGNDOFFID,
                                DECODE((SELECT DISTINCT BT1.LGNDOFFID
                                         FROM SO_BUFFER_TABLE_5 BT1
                                        WHERE BT1.STRPRODUCTNUMBER =
                                              BT.STRPRODUCTNUMBER
                                          AND (BT1.LGNDOFFID =
                                              BT.LGNDOFFID + 1)),
                                       NULL,
                                       'FALSE',
                                       'TRUE') AS NEXT_VAL_EXIST
                  FROM SO_BUFFER_TABLE_5 BT
                 ORDER BY BT.STRPRODUCTNUMBER) A
         WHERE DECODE((SELECT DISTINCT BT.LGNDOFFID
                        FROM SO_BUFFER_TABLE_5 BT
                       WHERE BT.STRPRODUCTNUMBER = A.STRPRODUCTNUMBER
                         AND (BT.LGNDOFFID + 1 = A.LGNDOFFID)),
                      NULL,
                      'FALSE',
                      'TRUE') = 'FALSE') A2
 WHERE A1.STRPRODUCTNUMBER = A2.STRPRODUCTNUMBER
   AND A1.ROW_NUM = A2.ROW_NUM) AD
   GROUP BY AD.STRPRODUCTNUMBER

主要查询由2个子查询A1和1组成。 A2 A1提取值的上限


20170L  876190  1
20170L  876207  2
20170L  876212  3
20170L  876215  4
20180T  876200  5
20180T  876211  6

而A2查询提取下限


20170L  876190  1
20170L  876205  2
20170L  876209  3
20170L  876215  4
20180T  876200  5
20180T  876205  6

然后我将它们组合起来得到这样的输出


20170L   876190
20170L   876205- 876207
20170L   876209- 876212
20170L   876215
20180T   876200
20180T   876205- 876211

我使用rownum作为ID来匹配相应的值。

最后我使用了WM_CONCAT函数来组合值以获得输出


20170L   876190, 876205- 876207, 876209- 876212, 876215
20180T   876200, 876205- 876211

希望有所帮助