September 1, 2005 at 11:34 pm
I need to generate a seqence number based on 2 grouping columns (company and ordernum in this exampe).
Sample Table
Company OrderNum Sku seq_num
A 1 123
A 1 234
B 2 123
So I need to create (or update) the table that has 1 and 2 in the seq_num for the first 2 rows and a 1 in the seq_num in the 3 row. This should be simple, but I'm drawing a blank.
Thanks
September 2, 2005 at 2:56 am
in a stored proc...
declare @t_seq table(Company char(1), OrderNum int, Sku int, seq_num int identity)
insert into @t_seq
select ...
select * from @t_seq
Jon
September 2, 2005 at 3:36 am
Well, it doesn't get 'simple' until SQL Server 2005, when we get a ROW_NUMBER() function.
However, in the meantime you can do like this:
create table #x
( company char(1) not null,
ordernum int not null,
sku int not null
)
insert #x select 'A', 1, 123
insert #x select 'A', 1, 234
insert #x select 'B', 2, 123
go
select company,
ordernum,
sku,
seq_num = ( select count(*)
from #x x2
where x2.company = x1.company
and x2.ordernum = x1.ordernum
and x2.sku <= x1.sku
)
from #x x1
go
drop table #x
go
company ordernum sku seq_num
------- ----------- ----------- -----------
A 1 123 1
A 1 234 2
B 2 123 1
/Kenneth
September 2, 2005 at 3:39 am
sorry - didn't read that very well did I
September 2, 2005 at 3:41 am
Happens to all of us, especially on Fridays
/Kenneth
September 2, 2005 at 9:35 am
I appreciate the responses, but still have a problem. I'm processing about 30 million rows and the subquery solution has been running now for about an hour and I suspect it will take a really long time. Any other thoughts?
Thanks,
Nancy
September 5, 2005 at 3:44 am
Is this a one-time operation, or do you plan doing it on a regular basis? 30 million rows will indeed take quite a while...
/Kenneth
September 5, 2005 at 6:47 am
If you have very large groups and only a small number of them, this could be faster:
create table #x
( company char(1) not null,
ordernum int not null,
sku int not null,
seq_num int null
)
insert #x select 'A', 1, 123, null
insert #x select 'A', 1, 234, null
insert #x select 'B', 2, 123, null
go
declare @i int
select @i = 0
update #x set @i = seq_num = @i + 1
where company = 'A' and ordernum = 1
select @i = 0
update #x set @i = seq_num = @i + 1
where company = 'B' and ordernum = 2
/* Repeat for each combination of company and ordernum (i.e use a cursor)... */
select * from #x
drop table #x
go
One problem, however, is that you cannot control the ordering of seq_num within the group with this query (can someone change it to achieve this?). But maybe this is not important, or maybe the data is implicitly ordered correctly (depending on the clustered index on your table).
September 5, 2005 at 7:54 am
Been doing some more thinking Try this:
create table #x
( company char(1) not null,
ordernum int not null,
sku int not null
)
create table #y
( company char(1) not null,
ordernum int not null,
sku int not null,
seq_num int identity(1, 1)
)
create table #z
( company char(1) not null,
ordernum int not null,
sku int not null,
seq_num int
)
insert #x select 'A', 1, 123
insert #x select 'A', 1, 234
insert #x select 'B', 2, 123
go
insert into #y (company, ordernum, sku)
select company, ordernum, sku from #x order by company, ordernum, sku
insert into #z select * from #y
update z1 set z1.seq_num = z1.seq_num - z2.minnumber
from #z z1 inner join
(
select company, ordernum, min(seq_num) - 1 as minnumber from #z group by company, ordernum
)
z2
on z1.company = z2.company and z1.ordernum = z2.ordernum
select * from #z
drop table #x
go
drop table #y
go
drop table #z
go
September 6, 2005 at 2:37 am
Last attempt for now, I think
create table DataTable
( company char(1) not null,
ordernum int not null,
sku int not null
)
go
create clustered index DataTableIndex on DataTable(company, ordernum, sku)
go
create table ResultTable
(
company char(1) not null,
ordernum int not null,
sku int not null,
seq_num int not null,
seq_num_temp int identity(1, 1)
)
go
create clustered index ResultTableIndex on ResultTable(company, ordernum, seq_num_temp)
go
create table GroupTable
(
company char(1) not null,
ordernum int not null,
minnumber int
)
go
create clustered index GroupTableIndex on GroupTable(company, ordernum, minnumber)
go
insert DataTable select 'A', 1, 123
insert DataTable select 'A', 1, 234
insert DataTable select 'B', 2, 123
insert DataTable select 'B', 2, 124
insert DataTable select 'B', 2, 125
go
insert into ResultTable (company, ordernum, sku, seq_num)
select company, ordernum, sku, 0 from DataTable order by company, ordernum, sku
insert into GroupTable
select company, ordernum, min(seq_num_temp) - 1 from ResultTable group by company, ordernum
update r
set r.seq_num = r.seq_num_temp - g.minnumber
from ResultTable r inner join GroupTable g
on r.company = g.company and r.ordernum = g.ordernum
go
select company, ordernum, sku, seq_num from ResultTable
drop table DataTable
go
drop table ResultTable
go
drop table GroupTable
go
September 6, 2005 at 11:32 am
I really appreciate all the creative solutions to this problem. I'll do some testing for performance and see what happens.
Thanks!
September 7, 2005 at 4:09 am
Kenneth's solution may be faster than mine, I have absolutely no idea, but please let us know what you find out...
September 7, 2005 at 9:33 am
Just one more thing!
Make sure you have indexes in place for the joins and that a you are getting seeks over only one table scan!
* Noel
September 7, 2005 at 10:12 pm
And if you do SELECT much more often than INSERT,DELETE, UPDATE, create computed column and make it = dbo.Function2ComputeSeqNumber(OrderNum).
Function must be :
SELECT COUNT(*) ...
where OderNum = @OrderNum and ... <= ...
_____________
Code for TallyGenerator
Viewing 14 posts - 1 through 13 (of 13 total)
You must be logged in to reply to this topic. Login to reply