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 |
|
nice123ej
Starting Member
48 Posts |
Posted - 2008-09-15 : 23:35:38
|
| HiI have this table called mydata-----------------------------------___xval___|___gcode__|___dord___|___dname__|_<NULL>___|____A_____|____10____|Mark______|_<NULL>___|____A_____|____20____|Thomas____|_<NULL>___|____C_____|____30____|Ken_______|_<NULL>___|____B_____|____40____|Lili______|_<NULL>___|____B_____|____50____|Paul______|_<NULL>___|____B_____|____60____|Sally_____|_<NULL>___|____B_____|____70____|Richard___|_<NULL>___|____C_____|____80____|Matt______|_<NULL>___|____C_____|____90____|Joey______|_<NULL>___|____C_____|___100____|Samantha__|_<NULL>___|____A_____|___110____|Ali_______|_<NULL>___|____A_____|___120____|Nancy_____|_<NULL>___|____A_____|___130____|David_____|_<NULL>___|____A_____|___140____|John______|_<NULL>___|____C_____|___150____|Caroline__|_<NULL>___|____C_____|___160____|Kate______|_<NULL>___|____C_____|___170____|Adam______|_<NULL>___|____C_____|___180____|Ahmed_____|_<NULL>___|____A_____|___190____|Nora______|_<NULL>___|____A_____|___200____|William___|-----------------------------------as you can see it has gcode values repeated in different placesI want to fill xval column with gcode distinct ordered by dordso i get this result-----------------------------------___xval___|___gcode__|___dord___|___dname__|___1______|____A_____|____10____|Mark______|___1______|____A_____|____20____|Thomas____|___2______|____C_____|____30____|Ken_______|___3______|____B_____|____40____|Lili______|___3______|____B_____|____50____|Paul______|___3______|____B_____|____60____|Sally_____|___3______|____B_____|____70____|Richard___|___4______|____C_____|____80____|Matt______|___4______|____C_____|____90____|Joey______|___4______|____C_____|___100____|Samantha__|___5______|____A_____|___110____|Ali_______|___5______|____A_____|___120____|Nancy_____|___5______|____A_____|___130____|David_____|___5______|____A_____|___140____|John______|___6______|____C_____|___150____|Caroline__|___6______|____C_____|___160____|Kate______|___6______|____C_____|___170____|Adam______|___6______|____C_____|___180____|Ahmed_____|___7______|____A_____|___190____|Nora______|___7______|____A_____|___200____|William___|-----------------------------------i can do it using Cursor but the requirement is to be done without Cursorswho can help me doing this? and how? |
|
|
khtan
In (Som, Ni, Yak)
17689 Posts |
Posted - 2008-09-15 : 23:52:51
|
yes. make use of the row_number() or rank() or maybe dense_rank() with over() function KH[spoiler]Time is always against us[/spoiler] |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-09-15 : 23:53:03
|
| [code]UPDATE tSET t.xval=cnt.Count + 1FROm YourTable tOUTER APPLY (SELECT TOP 1 dord FROM YourTable WHERE dord <t.dord ORDER BY dord DESC)prevOUTER APPLY (SELECT COUNT(DISTINCT gcode)AS Count FROM YourTable WHERE dord<t.dord AND (gcode <>t.gcode OR dord<=prev.dord)cnt[/code] |
 |
|
|
Vinnie881
Master Smack Fu Yak Hacker
1231 Posts |
Posted - 2008-09-16 : 00:04:58
|
here's a sampleDeclare @mytable table(xval int, Gcode varchar(2), dord int)insert into @mytable(gcode,dord)select 'a',100 union allselect 'a',200 union allselect 'a',300 union allselect 'b',400 union allselect 'b',500 union allselect 'c',600 union allselect 'd',700Update aset xval = a.myrankfrom(select dense_rank() over (order by gcode) as myrank,*from @mytable ) aselect * from @Mytable Success is 10% Intelligence, 70% Determination, and 22% Stupidity.\_/ _/ _/\_/ _/\_/ _/ _/- 881 |
 |
|
|
Vinnie881
Master Smack Fu Yak Hacker
1231 Posts |
Posted - 2008-09-16 : 00:19:01
|
I just noticed the GCode can not be grouped due to the grouping is in the order combined with the Gcode. Use visak's solution, it's very good. There were a couple very minor syntax errors, but to save you the headache here it is with sample data.Declare @mytable table(xval int, Gcode varchar(2), dord int)insert into @mytable(gcode,dord)select 'a',100 union allselect 'a',200 union allselect 'a',300 union allselect 'b',400 union allselect 'b',500 union allselect 'c',600 union allselect 'd',700 Union allselect 'a',800 Union allselect 'a',900UPDATE tSET t.xval= cnt.[Count] + 1FROm @mYTABLE tOUTER APPLY (SELECT TOP 1 dord FROM @Mytable WHERE dord <t.dord ORDER BY dord DESC)prevOUTER APPLY (SELECT COUNT(DISTINCT gcode)AS Count FROM @Mytable WHERE dord<t.dord AND (gcode <>t.gcode OR dord<=prev.dord)) cntselect * from @Mytable Success is 10% Intelligence, 70% Determination, and 22% Stupidity.\_/ _/ _/\_/ _/\_/ _/ _/- 881 |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-09-16 : 00:31:52
|
quote: Originally posted by Vinnie881 I just noticed the GCode can not be grouped do to the grouping is in the order. Use visak's solution. There were a couple very minor syntax errors, but to save you the headache here it is correctedDeclare @mytable table(xval int, Gcode varchar(2), dord int)insert into @mytable(gcode,dord)select 'a',100 union allselect 'a',200 union allselect 'a',300 union allselect 'b',400 union allselect 'b',500 union allselect 'c',600 union allselect 'd',700 Union allselect 'a',800 Union allselect 'a',900UPDATE tSET t.xval= cnt.[Count] + 1FROm @mYTABLE tOUTER APPLY (SELECT TOP 1 dord FROM @Mytable WHERE dord <t.dord ORDER BY dord DESC)prevOUTER APPLY (SELECT COUNT(DISTINCT gcode)AS Count FROM @Mytable WHERE dord<t.dord AND (gcode <>t.gcode OR dord<=prev.dord)) cntselect * from @Mytable Success is 10% Intelligence, 70% Determination, and 22% Stupidity.\_/ _/ _/\_/ _/\_/ _/ _/- 881
i just tested it again and seems like it needs some retweakingUPDATE tSET t.xval= cnt.[Count] + 1FROm @mYTABLE tOUTER APPLY (SELECT TOP 1 dord FROM @Mytable WHERE dord <t.dord AND gcode <> t.gcode ORDER BY dord DESC)prevOUTER APPLY (SELECT COUNT(DISTINCT gcode)AS Count FROM @Mytable WHERE dord<t.dord AND (gcode <>t.gcode OR dord<=prev.dord)) cntoutput-----------------------------xval Gcode dord----------- ----- -----------1 a 1001 a 2001 a 3002 b 4002 b 5003 c 6004 d 7005 a 8005 a 900 |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-09-16 : 02:57:00
|
| [code]Declare @mytable table(xval int, Gcode varchar(2), dord int)insert into @mytable(gcode,dord)select 'a',100 union allselect 'a',200 union allselect 'a',300 union allselect 'b',400 union allselect 'b',500 union allselect 'c',600 union allselect 'd',700 Union allselect 'a',800 Union allselect 'a',900 Union allselect 'd',1100 Union allselect 'a',1300 Union allselect 'a',1440 Union allselect 'a',1530 union allselect 'b',1540 union allselect 'b',1660 union allselect 'c',1875 union allselect 'd',1998 Union allselect 'a',2200 Union allselect 'a',2265 Union allselect 'd',2315 Union allselect 'a',2366 Union allselect 'a',3440 UPDATE rSET r.xval= res.cntFROm @mYTABLE rcross apply(SELECT COUNT(Gcode)AS cnt FROM(SELECT t.Gcode,prev.dord,min(t.dord) AS mindordFROM @mYTABLE tOUTER APPLY (SELECT TOP 1 dord FROM @Mytable WHERE dord <t.dord AND gcode <> t.gcode ORDER BY dord DESC)prevGROUP BY t.Gcode,prev.dord)tmpWHERE tmp.mindord <=r.dord)resselect * from @Mytablexval Gcode dord----------- ----- -----------1 a 1001 a 2001 a 3002 b 4002 b 5003 c 6004 d 7005 a 8005 a 9006 d 11007 a 13007 a 14407 a 15308 b 15408 b 16609 c 187510 d 199811 a 220011 a 226512 d 231513 a 236613 a 3440[/code] |
 |
|
|
nice123ej
Starting Member
48 Posts |
Posted - 2008-09-16 : 05:12:43
|
| thx visakh16 u r genius |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-09-16 : 05:17:47
|
quote: Originally posted by nice123ej thx visakh16 u r genius
you're welcome |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-09-16 : 05:36:14
|
Also see http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=110706Declare @mytable table(xval int, Gcode varchar(2), dord int, primary key (dord))insert into @mytable(gcode,dord)select 'a',100 union allselect 'a',200 union allselect 'a',300 union allselect 'b',400 union allselect 'b',500 union allselect 'c',600 union allselect 'd',700 Union allselect 'a',800 Union allselect 'a',900 Union allselect 'd',1100 Union allselect 'a',1300 Union allselect 'a',1440 Union allselect 'a',1530 union allselect 'b',1540 union allselect 'b',1660 union allselect 'c',1875 union allselect 'd',1998 Union allselect 'a',2200 Union allselect 'a',2265 Union allselect 'd',2315 Union allselect 'a',2366 Union allselect 'a',3440 declare @gcode varchar(2), @xval intselect top 1 @xval = 1, @gcode = gcodefrom @mytableorder by dordupdate @mytableset @xval = xval = case when gcode <> @gcode then @xval + 1 else @xval end, @gcode = gcodeselect *from @mytable E 12°55'05.63"N 56°04'39.26" |
 |
|
|
nice123ej
Starting Member
48 Posts |
Posted - 2008-09-16 : 06:12:50
|
| i liked the last solution,very smart |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-09-16 : 06:35:49
|
It works as long as there is a clustered index over dord. E 12°55'05.63"N 56°04'39.26" |
 |
|
|
nice123ej
Starting Member
48 Posts |
Posted - 2008-09-16 : 19:52:50
|
| what if there is no index over dord? then how to resolve it? |
 |
|
|
nice123ej
Starting Member
48 Posts |
Posted - 2008-09-16 : 20:24:11
|
| will this work?update @mytableset @xval = xval = case when tbl.gcode <> @gcode then @xval + 1 else @xval end, @gcode = tbl.gcodefrom @mytable tblorder by tbl.dord |
 |
|
|
Vinnie881
Master Smack Fu Yak Hacker
1231 Posts |
Posted - 2008-09-16 : 20:46:37
|
You can't have a order by on a update statement, that is why there is a clustered index added to the table to try to keep the order.Your query would work assuming that you set the variables <> to null prior. Also regarding this method; in the articles I read it suggest throwing in a anchor variable in to ensure the index is used. Since peso did not include one, it is likley it is not needed, but I just figured I'd relay my understanding (Also Note articles with this method normally state that newer versions of sql might not work in the same manor, so this type of query is not always a perfect solution)Declare @mytable table(xval int, Gcode varchar(2), dord int, primary key (dord))insert into @mytable(gcode,dord)select 'a',100 union allselect 'a',200 union allselect 'a',300 union allselect 'b',400 union allselect 'b',500 union allselect 'c',600 union allselect 'd',700 Union allselect 'a',800 Union allselect 'a',900 Union allselect 'd',1100 Union allselect 'a',1300 Union allselect 'a',1440 Union allselect 'a',1530 union allselect 'b',1540 union allselect 'b',1660 union allselect 'c',1875 union allselect 'd',1998 Union allselect 'a',2200 Union allselect 'a',2265 Union allselect 'd',2315 Union allselect 'a',2366 Union allselect 'a',3440 declare @xval int,@Gcode varchar(2),@dord intset @xval = 0set @gCODE = ''update tblacset @xval = xval = case when tbl.gcode <> @gcode then @xval + 1 else @xval end,@gcode = tbl.gcode,@dord = tbl.dordfrom @mytable tblselect * from @mytable Success is 10% Intelligence, 70% Determination, and 22% Stupidity.\_/ _/ _/\_/ _/\_/ _/ _/- 881 |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-09-17 : 01:42:52
|
If you just a permanent table in your real situation, kust query hint the update statement with tablock and index use.That approach is documented in Books Online. E 12°55'05.63"N 56°04'39.26" |
 |
|
|
|
|
|
|
|