Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
jamesg
Starting Member
1 Post |
Posted - 2002-04-09 : 12:01:23
|
| I have an archive table:ArchiveDate SomeValue Status2/3/2002, blah, Status13/3/2002, blah, Status24/3/2002, da blah, Status25/3/2002, da blah, Status16/3/2002, da blah, Status27/3/2002, Also blah, Status38/3/2002, Also blah, Status3My problem is that I need the date of status changes only (including when reverting to a previously used status) i.e. the following result set:ArchiveDate Status2/3/2002, Status13/3/2002, Status25/3/2002, Status16/3/2002, Status27/3/2002, Status3The only solution I can come up with (I don't use cursors) is to create a Status archive table to track only status changes.Any ideas?TIA |
|
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2002-04-09 : 14:07:24
|
Here are two different possible solutions. The first is a set based solution; the second is an iterative solution that uses a temp table rather than a cursor.--temp table for set-based solutioncreate table #temp ( ArchiveDate smalldatetime not null, Status tinyint not null)go--datainsert #temp values('2/3/02',1)insert #temp values('3/3/02',2)insert #temp values('5/3/02',1)insert #temp values('6/3/02',2)insert #temp values('7/3/02',3)insert #temp values('8/3/02',3)--temp tables for iterative solutionselect identity(int,1,1) as ident, *into #temp2from #temporder by ArchiveDate ASCselect *into #temp3from #tempdelete #temp3go--This is the set-based solutionselect ArchiveDate, Statusfrom #temp t1where Status <> coalesce(( select top 1 Status from #temp where t1.ArchiveDate > ArchiveDate order by ArchiveDate DESC),0)order by ArchiveDatego--This is the iterative solutiondeclare @ident int, @maxident intselect @ident = 1, @maxident = max(ident)from #temp2--loop throug the recordswhile @ident <= @maxidentbegin insert #temp3(ArchiveDate, Status) --special case for the first record select ArchiveDate, Status from #temp2 where ident = @ident and @ident = 1 union select a.ArchiveDate, a.Status from #temp2 a inner join #temp2 b on (a.ident = b.ident + 1 and a.Status <> b.Status) where a.ident = @ident set @ident = @ident + 1endselect ArchiveDate, Statusfrom #temp3order by ArchiveDatego--clean updrop table #tempdrop table #temp2drop table #temp3go Hope that helps. Good Luck!!<O> |
 |
|
|
jcelko
Esteemed SQL Purist
547 Posts |
Posted - 2002-04-10 : 16:09:02
|
| >> I have an archive table: .. <<It would have been nice to see the DDL for it, so we could answer your questions without guessing. My guess is that your schema is wrong. You want to archive events and events have a duration, so you should have had something like:CREATE TABLE Archives(keycolumn INTEGER NOT NULL PRIMARY KEY, ... start_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, end_date DATETIME, -- null means still current status CHAR(10) NOT NULL, ...);--CELKO--Joe Celko, SQL Guru |
 |
|
|
|
|
|
|
|