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 |
|
tim_buktoo
Starting Member
3 Posts |
Posted - 2005-03-14 : 12:42:53
|
| I have a table with 2 fields: ID and Date_visit. ID Date_visit101 1/1/01101 2/1/03101 3/5/04102 10/12/03102 12/15/04I'd like to transform the data so that it looks like:ID Date1 Date2 Date3101 1/1/01 2/1/03 3/5/04102 10/12/03 12/15/04After doing so, I can calculate (for each ID) the number of days between date1 and date2, date1 and date3, etc... in a seperate querySo the final query would have 4 fields (ID Date1 Date2 Date3).Does anyone know the best way to do this. Your help is greatly appreciated. |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
|
|
tim_buktoo
Starting Member
3 Posts |
Posted - 2005-03-14 : 12:55:30
|
quote: Originally posted by spirit1 take a look at:http://www.sqlteam.com/item.asp?ItemID=2955Go with the flow & have fun! Else fight the flow 
Thanks for the quick reply. I've attempted to create a pivot table in MS Access with the same table, but since I am not using a summary function (SUM(), AVG(), MIN(), MAX())for the dates, it wont work, and I dont want any sums or averages anyway. I want DATE1 to equal the first date (chronologically) it encounters for an ID, DATE2 to equal the next date (chronologically) it encounters, and so on and so forth. So my final product will be a single ID and (for the example provided above) 3 additional (DATE1,2,3) fields that took the stacked dates and put them on the same line.A pivot table will just count the number of times the date is present for a particular ID. It will not allow me to then compute a datediff on the dates. I'm not sure that I am being clear. Please let me know if this makes sense. |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2005-03-14 : 14:09:20
|
If you need the data pivoted, the link spirit1 provided is the way to go. However, run this and see if you can use the format this is providing. Its not pivoted but it will give you a ROW for each subsequent date_visit after the earliest one with the dateDiff as well.set nocount ondeclare @tb Table (ID int, Date_visit smalldatetime)insert @tbSelect 101, '1/1/2001' union allSelect 101, '2/1/2003' union allSelect 101, '3/5/2004' union allSelect 102, '10/12/2003' union allSelect 102, '12/15/2004'select a.ID ,b.Date_Visit Date_Visit_1st ,a.Date_Visit ,dateDiff(day, b.Date_Visit, a.Date_Visit) [DateVisitDiff]From @tb aJOIN ( Select [id], min(Date_Visit) Date_Visit From @tb Group by [id] ) b ON a.[id] = b.[id] and a.Date_Visit <> b.Date_VisitOrder by 1,2,3 Be One with the OptimizerTG |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2005-03-14 : 15:29:11
|
this'll help you...it works only for 2 columns for now.EDIT: fixed so it works for N columnscreate proc spTranspose@TableName varchar(100), @PrimaryCol varchar(100), -- parent column to transposing columns@SecondaryCol varchar(1000) -- CSV string of columns to transposeasselect @SecondaryCol = replace(@SecondaryCol, ' ', '')declare @i int, @tInc varchar(10), @tIncNext varchar(10), @Sql varchar(8000), @SqlSelect varchar(8000), @tempSql nvarchar(4000), @ColNum int select @i=1, @Sql = '', @SqlSelect = ''select @tempSql = 'select top 1 @ColNum = count(*) from ' + @TableName + ' group by ' + @PrimaryCol + ' order by 1 desc'exec sp_executesql @tempSql, N'@ColNum int output', @ColNum outputif object_id('tempdb..##temp_transpose') is not null drop table ##temp_transposeexec ('select identity (int, 1,1) as Transpose_Id, ' + @PrimaryCol + ', ' + @SecondaryCol + ' into ##temp_transpose from ' + @TableName + ' order by ' + @PrimaryCol + ', ' + @SecondaryCol)select @SqlSelect = 'select distinct t1.' + @PrimaryCol, @Sql = ' from ##temp_transpose t1'while @i<=@ColNumbegin set @tInc = 't' + cast(@i as varchar(10)) set @SqlSelect = @SqlSelect + ', ' + @tInc + '.'+ replace(@SecondaryCol, ',', ', ' + @tInc + '.') set @tIncNext = 't' + cast(@i+1 as varchar(10)) if @i<@ColNum set @Sql = @Sql + ' LEFT JOIN ##temp_transpose ' + @tIncNext + ' on t1.' + @PrimaryCol + ' = ' + @tIncNext + '.' + @PrimaryCol + ' and ' + @tInc + '.Transpose_Id = ' + @tIncNext + '.Transpose_Id-1 ' set @i = @i + 1endexec(@SqlSelect + @Sql + ' WHERE (select count(*) from ##temp_transpose where t1.' + @PrimaryCol + ' = ' + @PrimaryCol + ' and t1.Transpose_Id > Transpose_Id)=0')goexec spTranspose 'yourTableName', 'id', 'date_visit,'/*use northwindexec spTranspose 'orders', 'customerId', 'orderDate, shippedDate, employeeid'*/Go with the flow & have fun! Else fight the flow |
 |
|
|
tim_buktoo
Starting Member
3 Posts |
Posted - 2005-03-14 : 17:00:19
|
| This works great ! Thanks Spirit1 and TG for your help. It is much appreciated ! |
 |
|
|
dkw2002
Starting Member
2 Posts |
Posted - 2005-03-22 : 13:56:36
|
| Can you please tell me how to put the result in a table? Thanks very much!Dave |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2005-03-22 : 14:28:58
|
create table #temp (all of the columns you need)insert into #tempexec spTranspose 'yourTableName', 'id', 'date_visit,' -- or any other sproc callfor my sproc:or after calling the sproc you can still acces the data in global ##temp table ##temp_transpose:select * from ##temp_transposebecause the table gets droped when the sproc runs.Go with the flow & have fun! Else fight the flow |
 |
|
|
dkw2002
Starting Member
2 Posts |
Posted - 2005-03-22 : 21:21:02
|
| Thanks again!Dave |
 |
|
|
|
|
|
|
|