Соберите конкретные значения, соответствующие критериям, сгруппируйте последовательные значения - PullRequest
2 голосов
/ 21 июня 2011

Извините за запутанный заголовок, я не мог придумать лучшего способа его обработать.

У меня есть набор данных, где некоторые значения являются последовательными числами

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 ]

1 голос
/ 21 июня 2011
-- 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
0 голосов
/ 24 апреля 2012

Этот запрос выдает требуемый вывод

<code>
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 и A2. A1 извлекает верхний предел значений

<code>
20170L  876190  1
20170L  876207  2
20170L  876212  3
20170L  876215  4
20180T  876200  5
20180T  876211  6
* 1006.*

, в то время как запрос A2 извлекает нижний предел

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

Затем я объединил их, чтобы получить такой вывод

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

IЯ использовал rownum в качестве идентификатора для сопоставления с соответствующими значениями.

Наконец, я использовал функцию WM_CONCAT для объединения значений, чтобы получить выходные данные, такие как

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

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...