| Author | Topic | 
                            
                                    | sql_server_dbaPosting Yak  Master
 
 
                                        167 Posts | 
                                            
                                            |  Posted - 2010-05-11 : 18:18:42 
 |  
                                            | Hi All,  Can anybody please help me out to build a query for the below shown scenario....Here is the table which i have.....Col1   Col2          Col3(Version)1      Jan 1 2010    NULL1      Jan 3 2010    NULL1      Jan 10 2010   NULL2      Jan 1 2010    NULL2      Jan 20 2010   NULL2      Jan 4 2010    NULLNow i need to write a query to update the col3(Version) in such a way that, for the value of 1 in Col1, the Col3 needs to be updated with the version values based on Col2. So the output should look likeCol1   Col2          Col3(Version)1      Jan 1 2010    11      Jan 3 2010    21      Jan 10 2010   32      Jan 1 2010    12      Jan 4 2010    22      Jan 20 2010   3Really appreciate if someone can find a way to do this.   Thanks in Advance |  | 
       
                            
                       
                          
                            
                                    | ms65gConstraint Violating Yak Guru
 
 
                                    497 Posts | 
                                        
                                          |  Posted - 2010-05-11 : 18:34:40 
 |  
                                          | [code];WITH CTE AS(SELECT *,ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY Col2) AS RankFROM table_name)UPDATE CTESET Col3 = Rank[/code] |  
                                          |  |  | 
                            
                       
                          
                            
                                    | malpashaaConstraint Violating Yak Guru
 
 
                                    264 Posts | 
                                        
                                          |  Posted - 2010-05-11 : 18:38:47 
 |  
                                          | Would you specify the datatype of your columns (VARCHAR, DATETIME, ...) because this will affects the query. |  
                                          |  |  | 
                            
                       
                          
                            
                                    | malpashaaConstraint Violating Yak Guru
 
 
                                    264 Posts | 
                                        
                                          |  Posted - 2010-05-11 : 18:40:27 
 |  
                                          | quote:This will not work if Col2 datatype is VARCHAROriginally posted by ms65g
 
 ;WITH CTE AS(SELECT *,ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY Col2) AS RankFROM table_name)UPDATE CTESET Col3 = Rank 
 |  
                                          |  |  | 
                            
                       
                          
                            
                                    | ms65gConstraint Violating Yak Guru
 
 
                                    497 Posts | 
                                        
                                          |  Posted - 2010-05-11 : 18:58:43 
 |  
                                          | quote:If Col2 datatype is varchar we can convert the column to datetimeLike this:Originally posted by malpashaa
 
 quote:This will not work if Col2 datatype is VARCHAROriginally posted by ms65g
 
 ;WITH CTE AS(SELECT *,ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY Col2) AS RankFROM table_name)UPDATE CTESET Col3 = Rank 
 
 ;WITH CTE AS(SELECT *,ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY cast(col2 as datetime)) AS RankFROM @t)UPDATE CTESET Col3 = Rank |  
                                          |  |  | 
                            
                       
                          
                            
                                    | sql_server_dbaPosting Yak  Master
 
 
                                    167 Posts | 
                                        
                                          |  Posted - 2010-05-11 : 19:27:30 
 |  
                                          | Wow, that's really great. I just posted this one hour back and got the reply.Thanks ms65g and Pasha. I really appreciate the help which you guys did. Small request again(I am the beginner and have no knowledge on Queries :( ). I never used CTE and didn't understood a single step of your query( But it worked fine :)). Could you please explain me a little about CTE and how that works?Thanks |  
                                          |  |  | 
                            
                       
                          
                            
                                    | ms65gConstraint Violating Yak Guru
 
 
                                    497 Posts | 
                                        
                                          |  Posted - 2010-05-11 : 19:41:36 
 |  
                                          | Thanks, you can use derived table instead of CTE like this: UPDATE DSET Col3 = RankFROM (SELECT *,ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY Col2) AS Rank      FROM table_name) AS DSQL Server doesn't limit the actions against table expressions (derived tables, CTEs, views, and inline table-valued UDFs) to SELECT only, but also allows other DML statements against those (INSERT, UPDATE, DELETE). |  
                                          |  |  | 
                            
                       
                          
                            
                                    | sql_server_dbaPosting Yak  Master
 
 
                                    167 Posts | 
                                        
                                          |  Posted - 2010-05-11 : 19:42:16 
 |  
                                          | I should have posted before but just remembered about this....Here is the scenario...Now we updated the original table and next time when we insert some record, the record should get inserted in the table and the version should get updated too.Now we got this...Col1    Col2             Col3(Version)1       Jan 1 2010       11       Jan 3 2010       21       Jan 10 2010      32       Jan 1 2010       12       Jan 4 2010       22       Jan 20 2010      3When we insert a record with values (Col1 = 1, Col2 = Jan 6 2010) then the version should get updated accordingly and the table should look like this....Col1    Col2             Col3(Version)1       Jan 1 2010       11       Jan 3 2010       21       Jan 6 2010       31       Jan 10 2010      42       Jan 1 2010       12       Jan 4 2010       22       Jan 20 2010      3This is being done in a transaction..so cannot do this manually and also 100's of records will be inserted and they needs to be updated accordingly...It would be great if someone can help me on this. |  
                                          |  |  | 
                            
                       
                          
                            
                                    | ms65gConstraint Violating Yak Guru
 
 
                                    497 Posts | 
                                        
                                          |  Posted - 2010-05-11 : 19:47:58 
 |  
                                          | You can calculate the values of columns 3 at executing query time, and do not consider col3 in physicals designI mean: SELECT *, col3 = ROW_NUMBER() OVER(....) FROM table Also you can update the table every time that are rows inserted by using DML after insert trigger. |  
                                          |  |  | 
                            
                       
                          
                            
                                    | sql_server_dbaPosting Yak  Master
 
 
                                    167 Posts | 
                                        
                                          |  Posted - 2010-05-11 : 22:45:02 
 |  
                                          | ok..i will check with this in the morning and let you know what i have decided to do in a transaction. Thanks for your help on this. Appreciate it. |  
                                          |  |  | 
                            
                       
                          
                            
                                    | Julien.CrawfordStarting Member
 
 
                                    21 Posts | 
                                        
                                          |  Posted - 2010-05-12 : 01:45:45 
 |  
                                          | This might be a little old school, but this is how I usually do this type of thing.// assuming clusted index on col1,col2 (if not you'll need a temp table with this index)drop table tgocreate table t (col1 int not null, col2 datetime not null, col3 int null, primary key (col1,col2))goinsert into t (col1,col2) select 1, '1 jan 2010'insert into t (col1,col2) select 1, '3 jan 2010'insert into t (col1,col2) select 1, '5 jan 2010'insert into t (col1,col2) select 1, '8 jan 2010'insert into t (col1,col2) select 2, '1 jan 2010'insert into t (col1,col2) select 2, '4 jan 2010'insert into t (col1,col2) select 2, '12 jan 2010'select * from tdeclare @n intset		@n = 0declare @PrevCol1 intset		@PrevCol1 = 0update	tset		@n = case when @PrevCol1 = col1 then @n + 1 else 1 end	,	col3 = case when @PrevCol1 = col1 then @n + 1 else 1 end	,	@PrevCol1 = col1select * from t |  
                                          |  |  | 
                            
                       
                          
                            
                                    | Julien.CrawfordStarting Member
 
 
                                    21 Posts | 
                                        
                                          |  Posted - 2010-05-12 : 01:58:19 
 |  
                                          | I wrote this on sybase12.5 and it differs from sqlserver2005Here is the ammended versionNote the initial value of 0 rather than 1 - Interesting.drop table tgocreate table t (col1 int not null, col2 datetime not null, col3 int null, primary key (col1,col2))goinsert into t (col1,col2) select 1, '1 jan 2010'insert into t (col1,col2) select 1, '3 jan 2010'insert into t (col1,col2) select 1, '5 jan 2010'insert into t (col1,col2) select 1, '8 jan 2010'insert into t (col1,col2) select 2, '1 jan 2010'insert into t (col1,col2) select 2, '4 jan 2010'insert into t (col1,col2) select 2, '12 jan 2010'select * from tdeclare @n intset @n = 0declare @PrevCol1 intset @PrevCol1 = 0update tset @n = case when @PrevCol1 = col1 then @n + 1 else 0 end, col3 = case when @PrevCol1 = col1 then @n + 1 else 0 end, @PrevCol1 = col1select * from t |  
                                          |  |  | 
                            
                       
                          
                            
                                    | Julien.CrawfordStarting Member
 
 
                                    21 Posts | 
                                        
                                          |  Posted - 2010-05-12 : 18:27:42 
 |  
                                          | also, its a single pass - I'd be surprised (nicely) if there is any means of getting better performance. |  
                                          |  |  | 
                            
                       
                          
                            
                                    | sql_server_dbaPosting Yak  Master
 
 
                                    167 Posts | 
                                        
                                          |  Posted - 2010-05-12 : 21:53:53 
 |  
                                          | Yeah even this one worked. Perfect...Thanks for your reply Julien. |  
                                          |  |  | 
                            
                            
                                |  |