all groups > sql server programming > october 2007 >
You're in the sql server programming group:
Update row from values in another row in same table
sql server programming:
I would like help in writing an Update query that updates a row by its key from values from another row by its key. There are many columns (10) to be undated, but for this example I will settle for updating a single column. For example: CREATE TABLE [tblTest] ( [Rev] [int] NOT NULL , [ID] [int] NOT NULL , [Field1] [int] NOT NULL , CONSTRAINT [PK_tblTest] PRIMARY KEY CLUSTERED ( [Rev], [ID] ) ON [PRIMARY] ) ON [PRIMARY] GO Rev ID Field1 ----------- ----------- ----------- 97 1 10 97 2 20 97 3 30 98 2 22 98 3 30 98 4 40 99 1 10 99 2 20 (8 row(s) affected) The example table has sets (Revs) of records, 97, 98 and 99 and so on . I want to Update the last rec above (Rev 99 and ID 2) with the values from (Rev 97 ID 2). If I can do this without a temp table that would be great. Maybe a subquery or something? So that row 99 would be: 99 2 22 I have tried (and many, many other things): SET t1.Field1 = t2.Field1 FROM tblTest AS t1 INNER JOIN tblTest AS t2 ON t1.ID = t2.ID WHERE t1.Rev = 97 AND t2.Rev = 99 Of course this gives an error. I would appreciate any ideas or help.
[quoted text, click to view] "xMan" wrote: > I would like help in writing an Update query that updates a row by its key > from values from another row by its key. There are many columns (10) to be > undated, but for this example I will settle for updating a single column. For > example: > > CREATE TABLE [tblTest] ( > [Rev] [int] NOT NULL , > [ID] [int] NOT NULL , > [Field1] [int] NOT NULL , > CONSTRAINT [PK_tblTest] PRIMARY KEY CLUSTERED > ( > [Rev], > [ID] > ) ON [PRIMARY] > ) ON [PRIMARY] > GO > > Rev ID Field1 > ----------- ----------- ----------- > 97 1 10 > 97 2 20 > 97 3 30 > 98 2 22 > 98 3 30 > 98 4 40 > 99 1 10 > 99 2 20 > > (8 row(s) affected) > The example table has sets (Revs) of records, 97, 98 and 99 and so on . I > want to Update the last rec above (Rev 99 and ID 2) with the values from (Rev > 97 ID 2). If I can do this without a temp table that would be great. Maybe a > subquery or something? > > So that row 99 would be: > 99 2 22 > > I have tried (and many, many other things): > > SET t1.Field1 = t2.Field1 > FROM tblTest AS t1 INNER JOIN > tblTest AS t2 ON t1.ID = t2.ID > WHERE t1.Rev = 97 AND t2.Rev = 99 > > Of course this gives an error. I would appreciate any ideas or help. > Thanks in advance. XMan
Opps I missed the 1st line of the SQL when I copied it. It should be: UPDATE tblTest SET t1.Field1 = t2.Field1 FROM tblTest AS t1 INNER JOIN tblTest AS t2 ON t1.ID = t2.ID
I really appreciate your help on this!!!! However I get the following error when I paste this into EM: Error in table name or view name in UPDATE clause. Unable to parse query text. I then remove the T1 from line 1 and get: Then it shows: Incorrect syntax error near 'T1' then: Cannot use the column prefix 'T1' .... any other ideas? Thanks again for your help. xMan [quoted text, click to view] "Awlnoing" wrote: > If you drop the t1. from the SET (or add the t1 alias to the UPDATE ) it > should work. > > UPDATE tblTest t1 > SET t1.Field1 = t2.Field1 > FROM tblTest AS t1 INNER JOIN > tblTest AS t2 ON t1.ID = t2.ID > WHERE t1.Rev = 97 AND t2.Rev = 99 > > or > > UPDATE tblTest > SET Field1 = t2.Field1 > FROM tblTest AS t1 INNER JOIN > tblTest AS t2 ON t1.ID = t2.ID > WHERE t1.Rev = 97 AND t2.Rev = 99 > > > "xMan" <xMan@discussions.microsoft.com> wrote in message > news:D66E22A3-D2B1-4894-A1F0-38BBFCB2BDCC@microsoft.com... > > > > > > "xMan" wrote: > > > >> I would like help in writing an Update query that updates a row by its > >> key > >> from values from another row by its key. There are many columns (10) to > >> be > >> undated, but for this example I will settle for updating a single column. > >> For > >> example: > >> > >> CREATE TABLE [tblTest] ( > >> [Rev] [int] NOT NULL , > >> [ID] [int] NOT NULL , > >> [Field1] [int] NOT NULL , > >> CONSTRAINT [PK_tblTest] PRIMARY KEY CLUSTERED > >> ( > >> [Rev], > >> [ID] > >> ) ON [PRIMARY] > >> ) ON [PRIMARY] > >> GO > >> > >> Rev ID Field1 > >> ----------- ----------- ----------- > >> 97 1 10 > >> 97 2 20 > >> 97 3 30 > >> 98 2 22 > >> 98 3 30 > >> 98 4 40 > >> 99 1 10 > >> 99 2 20 > >> > >> (8 row(s) affected) > >> The example table has sets (Revs) of records, 97, 98 and 99 and so on . I > >> want to Update the last rec above (Rev 99 and ID 2) with the values from > >> (Rev > >> 97 ID 2). If I can do this without a temp table that would be great. > >> Maybe a > >> subquery or something? > >> > >> So that row 99 would be: > >> 99 2 22 > >> > >> I have tried (and many, many other things): > >> > >> SET t1.Field1 = t2.Field1 > >> FROM tblTest AS t1 INNER JOIN > >> tblTest AS t2 ON t1.ID = t2.ID > >> WHERE t1.Rev = 97 AND t2.Rev = 99 > >> > >> Of course this gives an error. I would appreciate any ideas or help. > >> Thanks in advance. XMan > > > > Opps I missed the 1st line of the SQL when I copied it. It should be: > > UPDATE tblTest > > SET t1.Field1 = t2.Field1 > > FROM tblTest AS t1 INNER JOIN > > tblTest AS t2 ON t1.ID = t2.ID > > WHERE t1.Rev = 97 AND t2.Rev = 99 > >
If you drop the t1. from the SET (or add the t1 alias to the UPDATE ) it should work. UPDATE tblTest t1 SET t1.Field1 = t2.Field1 FROM tblTest AS t1 INNER JOIN tblTest AS t2 ON t1.ID = t2.ID WHERE t1.Rev = 97 AND t2.Rev = 99 or UPDATE tblTest SET Field1 = t2.Field1 FROM tblTest AS t1 INNER JOIN tblTest AS t2 ON t1.ID = t2.ID WHERE t1.Rev = 97 AND t2.Rev = 99 [quoted text, click to view] "xMan" <xMan@discussions.microsoft.com> wrote in message news:D66E22A3-D2B1-4894-A1F0-38BBFCB2BDCC@microsoft.com... > > > "xMan" wrote: > >> I would like help in writing an Update query that updates a row by its >> key >> from values from another row by its key. There are many columns (10) to >> be >> undated, but for this example I will settle for updating a single column. >> For >> example: >> >> CREATE TABLE [tblTest] ( >> [Rev] [int] NOT NULL , >> [ID] [int] NOT NULL , >> [Field1] [int] NOT NULL , >> CONSTRAINT [PK_tblTest] PRIMARY KEY CLUSTERED >> ( >> [Rev], >> [ID] >> ) ON [PRIMARY] >> ) ON [PRIMARY] >> GO >> >> Rev ID Field1 >> ----------- ----------- ----------- >> 97 1 10 >> 97 2 20 >> 97 3 30 >> 98 2 22 >> 98 3 30 >> 98 4 40 >> 99 1 10 >> 99 2 20 >> >> (8 row(s) affected) >> The example table has sets (Revs) of records, 97, 98 and 99 and so on . I >> want to Update the last rec above (Rev 99 and ID 2) with the values from >> (Rev >> 97 ID 2). If I can do this without a temp table that would be great. >> Maybe a >> subquery or something? >> >> So that row 99 would be: >> 99 2 22 >> >> I have tried (and many, many other things): >> >> SET t1.Field1 = t2.Field1 >> FROM tblTest AS t1 INNER JOIN >> tblTest AS t2 ON t1.ID = t2.ID >> WHERE t1.Rev = 97 AND t2.Rev = 99 >> >> Of course this gives an error. I would appreciate any ideas or help. >> Thanks in advance. XMan > > Opps I missed the 1st line of the SQL when I copied it. It should be: > UPDATE tblTest > SET t1.Field1 = t2.Field1 > FROM tblTest AS t1 INNER JOIN > tblTest AS t2 ON t1.ID = t2.ID > WHERE t1.Rev = 97 AND t2.Rev = 99
Hi Untested UPDATE tblTest SET Field1=( SELECT TOP 1 Field1 FROM tblTest WHERE ID=2 AND Rev<(SELECT MAX(Rev)FROM tblTest) ORDER BY Rev DESC) WHERE Rev=(SELECT MAX(Rev)FROM tblTest) AND ID=(SELECT MAX(ID)FROM tblTest WHERE Rev=(SELECT MAX(Rev)FROM tblTest)) [quoted text, click to view] "xMan" <xMan@discussions.microsoft.com> wrote in message news:A3AB908E-6298-4C4D-AFD4-AB49C7D0F789@microsoft.com... >I would like help in writing an Update query that updates a row by its key > from values from another row by its key. There are many columns (10) to be > undated, but for this example I will settle for updating a single column. > For > example: > > CREATE TABLE [tblTest] ( > [Rev] [int] NOT NULL , > [ID] [int] NOT NULL , > [Field1] [int] NOT NULL , > CONSTRAINT [PK_tblTest] PRIMARY KEY CLUSTERED > ( > [Rev], > [ID] > ) ON [PRIMARY] > ) ON [PRIMARY] > GO > > Rev ID Field1 > ----------- ----------- ----------- > 97 1 10 > 97 2 20 > 97 3 30 > 98 2 22 > 98 3 30 > 98 4 40 > 99 1 10 > 99 2 20 > > (8 row(s) affected) > The example table has sets (Revs) of records, 97, 98 and 99 and so on . I > want to Update the last rec above (Rev 99 and ID 2) with the values from > (Rev > 97 ID 2). If I can do this without a temp table that would be great. Maybe > a > subquery or something? > > So that row 99 would be: > 99 2 22 > > I have tried (and many, many other things): > > SET t1.Field1 = t2.Field1 > FROM tblTest AS t1 INNER JOIN > tblTest AS t2 ON t1.ID = t2.ID > WHERE t1.Rev = 97 AND t2.Rev = 99 > > Of course this gives an error. I would appreciate any ideas or help. > Thanks in advance. XMan
[quoted text, click to view] "xMan" <xMan@discussions.microsoft.com> wrote in message news:C2699D0D-3076-4961-84B7-575AB080C400@microsoft.com... >I really appreciate your help on this!!!! > > However I get the following error when I paste this into EM: > > Error in table name or view name in UPDATE clause. > Unable to parse query text. > > I then remove the T1 from line 1 > > and get: > > Then it shows: > Incorrect syntax error near 'T1' > > then: > > Cannot use the column prefix 'T1' .... > > > any other ideas? > Thanks again for your help. xMan >
Don't use EM for testing code. Use Query Analyzer. I think you'll need to make some changes though because both his suggestions cause errors when I tried them. Try this: CREATE TABLE [tblTest] ( [Rev] [int] NOT NULL , [ID] [int] NOT NULL , [Field1] [int] NOT NULL , CONSTRAINT [PK_tblTest] PRIMARY KEY CLUSTERED ( [Rev], [ID] ) ON [PRIMARY] ) ON [PRIMARY] GO INSERT INTO tblTest (Rev, ID, Field1) VALUES (97,1,1); INSERT INTO tblTest (Rev, ID, Field1) VALUES (99,1,2); UPDATE t1 SET t1.Field1 = t2.Field1 FROM tblTest AS t1 JOIN tblTest AS t2 ON t1.ID = t2.ID WHERE t1.Rev = 97 AND t2.Rev = 99; SELECT * FROM tblTest; Result: Rev ID Field1 ----------- ----------- ----------- 97 1 2 99 1 2 (2 row(s) affected) -- David Portas
That worked perfectly. Wonderful. Thank-You!!!! I rephrased the Update to: UPDATE tblTest SET Field1=(SELECT Field1 FROM tblTest WHERE ID=2 AND Rev=97) SET Field2=(SELECT Field2 FROM tblTest WHERE ID=2 AND Rev=97) . . WHERE Rev=(99) AND ID=(2) Is this the simplest way of handleing multiple fields? Thanks again. xMan [quoted text, click to view] "Uri Dimant" wrote: > Hi > Untested > > UPDATE tblTest SET Field1=( > SELECT TOP 1 Field1 FROM tblTest WHERE ID=2 AND Rev<(SELECT MAX(Rev)FROM > tblTest) > ORDER BY Rev DESC) > WHERE Rev=(SELECT MAX(Rev)FROM tblTest) > AND ID=(SELECT MAX(ID)FROM tblTest WHERE Rev=(SELECT MAX(Rev)FROM tblTest)) > > > "xMan" <xMan@discussions.microsoft.com> wrote in message > news:A3AB908E-6298-4C4D-AFD4-AB49C7D0F789@microsoft.com... > >I would like help in writing an Update query that updates a row by its key > > from values from another row by its key. There are many columns (10) to be > > undated, but for this example I will settle for updating a single column. > > For > > example: > > > > CREATE TABLE [tblTest] ( > > [Rev] [int] NOT NULL , > > [ID] [int] NOT NULL , > > [Field1] [int] NOT NULL , > > CONSTRAINT [PK_tblTest] PRIMARY KEY CLUSTERED > > ( > > [Rev], > > [ID] > > ) ON [PRIMARY] > > ) ON [PRIMARY] > > GO > > > > Rev ID Field1 > > ----------- ----------- ----------- > > 97 1 10 > > 97 2 20 > > 97 3 30 > > 98 2 22 > > 98 3 30 > > 98 4 40 > > 99 1 10 > > 99 2 20 > > > > (8 row(s) affected) > > The example table has sets (Revs) of records, 97, 98 and 99 and so on . I > > want to Update the last rec above (Rev 99 and ID 2) with the values from > > (Rev > > 97 ID 2). If I can do this without a temp table that would be great. Maybe > > a > > subquery or something? > > > > So that row 99 would be: > > 99 2 22 > > > > I have tried (and many, many other things): > > > > SET t1.Field1 = t2.Field1 > > FROM tblTest AS t1 INNER JOIN > > tblTest AS t2 ON t1.ID = t2.ID > > WHERE t1.Rev = 97 AND t2.Rev = 99 > > > > Of course this gives an error. I would appreciate any ideas or help. > > Thanks in advance. XMan > >
Thanks to all, That is exactly what I was looking for. You guys are the best. xMan [quoted text, click to view] "Hugo Kornelis" wrote: > On Sun, 14 Oct 2007 10:16:00 -0700, xMan wrote: > > >That worked perfectly. Wonderful. Thank-You!!!! > > > >I rephrased the Update to: > > > >UPDATE tblTest > > SET Field1=(SELECT Field1 FROM tblTest WHERE ID=2 AND Rev=97) > > SET Field2=(SELECT Field2 FROM tblTest WHERE ID=2 AND Rev=97) > > . > > . > >WHERE Rev=(99) AND ID=(2) > > > >Is this the simplest way of handleing multiple fields? Thanks again. xMan > > Hi xMan, > > No, it's not. Unfortunately, apart from the fact that repeating the same > subquery over and over is clumsy, the optimizer also does a poor job of > optimizing these queries. > > You'll get shorter and easier to maintain code plus faster execution if > you use the T-SQL proprietary version of the update command instead. But > do please beware of the issues this has if there's no perfect 1 on 1 > match (Google for details). > > UPDATE dest > SET column1 = src.column1, > column2 = src.column2, > ... > FROM tblTest AS dest > INNER JOIN tblTest AS src > ON src.ID = dest.ID > AND src.Rev = 97 > WHERE dest.ID = 2 > AND dest.Rev = 99; > > -- > Hugo Kornelis, SQL Server MVP > My SQL Server blog: http://sqlblog.com/blogs/hugo_kornelis
[quoted text, click to view] On Sun, 14 Oct 2007 10:16:00 -0700, xMan wrote: >That worked perfectly. Wonderful. Thank-You!!!! > >I rephrased the Update to: > >UPDATE tblTest > SET Field1=(SELECT Field1 FROM tblTest WHERE ID=2 AND Rev=97) > SET Field2=(SELECT Field2 FROM tblTest WHERE ID=2 AND Rev=97) > . > . >WHERE Rev=(99) AND ID=(2) > >Is this the simplest way of handleing multiple fields? Thanks again. xMan
Hi xMan, No, it's not. Unfortunately, apart from the fact that repeating the same subquery over and over is clumsy, the optimizer also does a poor job of optimizing these queries. You'll get shorter and easier to maintain code plus faster execution if you use the T-SQL proprietary version of the update command instead. But do please beware of the issues this has if there's no perfect 1 on 1 match (Google for details). UPDATE dest SET column1 = src.column1, column2 = src.column2, ... FROM tblTest AS dest INNER JOIN tblTest AS src ON src.ID = dest.ID AND src.Rev = 97 WHERE dest.ID = 2 AND dest.Rev = 99; -- Hugo Kornelis, SQL Server MVP
Don't see what you're looking for? Try a search.
|
|
|