Solved

select multiple range of records in a table

Posted on 2004-09-23
7
630 Views
Last Modified: 2012-06-27
Hello Experts!

Im having problem figuring out how to ask my problem i think its best to just give the sample data and my expected result.

here is the data:

mitch,    1
mitch,    2
mitch,    3
experts, 4
experts, 5
experts, 6
experts, 7
mitch,    8
experts, 9
experts, 10
experts, 11
mitch,    12
mitch,    13


here's the result i want to have:

mitch,    1-3
mitch,    8-8
mitch,    12-13
experts, 4-7
experts, 9-11

any help please! =)
and also where can you suggest a site for advance or complex SQL articles, tutorial or forum.

thnks guys!


 
0
Comment
Question by:lirmit
  • 4
  • 2
7 Comments
 
LVL 10

Expert Comment

by:imrancs
Comment Utility

declare @name as varchar(100)
declare @range as int
declare @PreName as varchar(100)
declare @from int
declare @to int

drop table #result
create table #result(name varchar(100), range varchar(100))

Declare Cur_Ranges Cursor for Select * from Ranges


Open  Cur_Ranges

Fetch Next From Cur_Ranges Into @name, @range
set @PreName = @name
set @from = @range

While @@Fetch_Status = 0
Begin
      if @Name = @PreName
            set @to = @range
      else
   begin
            insert into #result values(@prename, cast(@from as varchar) + ' - ' + cast(@to as varchar))
            set @from = @range
      end
set @PreName = @name
Fetch Next From Cur_Ranges Into @name, @range

End

close cur_ranges
deallocate cur_ranges

select * from #result


Imran
0
 
LVL 10

Expert Comment

by:imrancs
Comment Utility
Sorry my above post has some errors, here is updated version alongwith the sample data

/*create table ranges(name varchar(100), range int)


insert into ranges values('mitch',    1)
insert into ranges values('mitch',    2)
insert into ranges values('mitch',    3)
insert into ranges values('experts', 4)
insert into ranges values('experts', 5)
insert into ranges values('experts', 6)
insert into ranges values('experts', 7)
insert into ranges values('mitch',    8)
insert into ranges values('experts', 9)
insert into ranges values('experts', 10)
insert into ranges values('experts', 11)
insert into ranges values('mitch',    12)
insert into ranges values('mitch',    13)
*/


declare @name as varchar(100)
declare @range as int
declare @PreName as varchar(100)
declare @from int
declare @to int

if object_id('tempdb..#result') Is Not Null
drop table tempdb..#result

create table #result(name varchar(100), range varchar(100))

Declare Cur_Ranges Cursor for Select name, range  from Ranges order by id


Open  Cur_Ranges

Fetch Next From Cur_Ranges Into @name, @range
set @PreName = @name
set @from = @range

While @@Fetch_Status = 0
Begin
      Print(@PreName + '    ' +@Name + '    ' + Cast(@Range as varchar))
      if @Name = @PreName
            set @to = @range
      else
   begin
            insert into #result values(@prename, cast(@from as varchar) + ' - ' + cast(@to as varchar))
            set @from = @range
            set @to = @range
            set @PreName = @name
      end
 
Fetch Next From Cur_Ranges Into @name, @range

End

insert into #result values(@prename, cast(@from as varchar) + ' - ' + cast(@to as varchar))

close cur_ranges
deallocate cur_ranges

select * from #result order by 1 desc




Imran
0
 
LVL 18

Accepted Solution

by:
ShogunWade earned 150 total points
Comment Utility
This is how i would do it ( no cursors):

select small.name,small.val,MIN(big.val) FROM
      (select name,val from mytable a where not exists(select 1 from mytable where name=a.name and val=a.val-1)) small
      INNER JOIN
      (select name,val from mytable a where not exists(select 1 from mytable where name=a.name and val=a.val+1)) big
     ON small.name=big.name and small.val<=big.val
GROUP BY small.name,small.val


How it works:

1) (select name,val from mytable a where not exists(select 1 from mytable where name=a.name and val=a.val-1))  
    this returns a set of names and values where a the value - 1 doesnt exist   ie the minimums foreach range

2) (select name,val from mytable a where not exists(select 1 from mytable where name=a.name and val=a.val+1))
   this is the same but gets the maximums

3)  these are joined together by name and value but the small.val cant be smallr than the big.val

4)  at this point your results should be like this:

mitch 1 3
mitch 1 8
mitch 1 13
mitch 8 8
mitch 8 13
mitch 13 13
..etc.

5)  grouping by name and the small.val  and taking the MIN(big.val)  eliminates the eronious ones like
mitch 1 8
mitch 1 13

6)  hey presto.
0
Control application downtime with dependency maps

Visualize the interdependencies between application components better with Applications Manager's automated application discovery and dependency mapping feature. Resolve performance issues faster by quickly isolating problematic components.

 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
Comment Utility
unfortunatley, imrancs' suggestion is not 100% complete (I assume not tested :-)
there are several bugs in it, here comes a tested version.
I assume the table to be called RANGES, with the columns NAME and RANGE, please adjust as your names.


declare @name as varchar(100)
declare @range as int
declare @prerange as int
declare @PreName as varchar(100)
declare @from int
declare @to int

drop table #result
create table #result(name varchar(100), range varchar(100))

Declare Cur_Ranges Cursor for Select name, range from Ranges order by name, range

Open  Cur_Ranges

Fetch Next From Cur_Ranges Into @name, @range

While @@Fetch_Status = 0
Begin
     if @prename is null
      begin
            set @prename = @name
            set @from = @range
            set @to = @range
      end
     else
     if (@Name = @PreName) and (@range = (@to + 1))
         set @to = @range
     else
        begin
          insert into #result values(@prename, cast(@from as varchar) + ' - ' + cast(@to as varchar))
          set @from = @range
        set @to = @range
        end

  set @PreName = @name
  Fetch Next From Cur_Ranges Into @name, @range
End

if @name is not null
   insert into #result values(@prename, cast(@from as varchar) + ' - ' + cast(@to as varchar))


close cur_ranges
deallocate cur_ranges

select * from #result
select * from ranges


Cheers
0
 
LVL 10

Expert Comment

by:imrancs
Comment Utility
angelIII, yes i agree with you my first post has several bugs, but I have corrected them in my next post.


Imran
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
Comment Utility
Sorry, hadn't seen the second post before posting mine... good job!
0
 
LVL 10

Expert Comment

by:imrancs
Comment Utility
angelIII,

its okey

0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Performance is the key factor for any successful data integration project, knowing the type of transformation that you’re using is the first step on optimizing the SSIS flow performance, by utilizing the correct transformation or the design alternat…
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
Via a live example, show how to backup a database, simulate a failure backup the tail of the database transaction log and perform the restore.
Via a live example, show how to set up a backup for SQL Server using a Maintenance Plan and how to schedule the job into SQL Server Agent.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now