Oracle consecutive sequence numbers acquired in range SQL

Here's a simple inventory list, code represents the serial number, the representative of the format is the format of the serial number. Each record represents a stock record.

 

 Now there is such a demand, the sequential serial numbers to the range to find out. Expected results are as follows:

 

 

What should be realized this need?

Scheme 1: Loading the data of the entire table into memory, by looping through, and find the start FormatA FormatB end serial number. A small amount of inventory records are not a problem. But if the stock reached a record on 10 million, or running out of memory problems is clearly prone to slow.

Scheme 2: SEQ ID NO Format same format in order to merge a record using SQL.

Oracle provides XMLAGG function sequence number may be spliced together, the return type is CLOB a certain order. LISTAGG functions also provide similar functionality, but the maximum length is 4000 characters. Table Stock SEQ ID spliced together is often more than 4000 characters, so here XMLAGG function is selected. Specific reference: https://blog.csdn.net/zqkwcyx/article/details/88663982

SQL provides the following example:

 

with inventory as(
select 'FormatA' as numFormat, 0001 as code from dual union
select 'FormatA' as numFormat, 0002 as code from dual union
select 'FormatA' as numFormat, 0003 as code from dual union
select 'FormatA' as numFormat, 0005 as code from dual union
select 'FormatA' as numFormat, 0006 as code from dual union
select 'FormatA' as numFormat, 0008 as code from dual union
select 'FormatB' as numFormat, 0001 as code from dual union
select 'FormatB' as numFormat, 0002 as code from dual union
select 'FormatB' as numFormat, 0005 as code from dual union
select 'FormatB' as numFormat, 0006 as code from dual union
select 'FormatB' as numFormat, 0008 as code from dual union
select 'FormatB' as numFormat, 0009 as code from dual
)
select numformat,rtrim(xmlagg(XMLELEMENT(e,orig.code,',').EXTRACT('//text()') order by orig.code).GetClobVal(),',') NumberClob from (
SELECT * FROM inventory
) orig
group by orig.numFormat
;

 

 And also through the loop through, and to find FormatA FormatB the start and end sequence number.

ICP 1, check out the number of records to be much less problems Option 1 does not occur. The disadvantage is that still needs to be loaded into memory, cycle through on CPU consumption is relatively large.

 

Scenario 3: Can you avoid traversing in memory directly using SQL to find the serial number range it? The answer is yes, reference lag, lead function.

https://blog.csdn.net/weixin_41287692/article/details/80577828

Thank former colleague Frank ideas offered, I made some changes in his foundation, remove some redundant field.

 

with inventory as(
select 'FormatA' as numFormat, 0001 as code from dual union
select 'FormatA' as numFormat, 0002 as code from dual union
select 'FormatA' as numFormat, 0003 as code from dual union
select 'FormatA' as numFormat, 0005 as code from dual union
select 'FormatA' as numFormat, 0006 as code from dual union
select 'FormatA' as numFormat, 0008 as code from dual union
select 'FormatB' as numFormat, 0001 as code from dual union
select 'FormatB' as numFormat, 0002 as code from dual union
select 'FormatB' as numFormat, 0005 as code from dual union
select 'FormatB' as numFormat, 0006 as code from dual union
select 'FormatB' as numFormat, 0008 as code from dual union
select 'FormatB' as numFormat, 0009 as code from dual
)
select numFormat,code startNum, nvl(lead(previousCode) over(partition BY numFormat order by previousCode nulls first ),maxn) endNum from(

select numFormat,
lag(code, 1) over(partition by numFormat order by code) previousCode, code,
max(code) over(partition by numFormat) maxn
from inventory

)
where nvl(code-previousCode-1,1) <> 0
;

 

Guess you like

Origin www.cnblogs.com/pmh905001/p/12241898.html