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 |
23Soul
Starting Member
3 Posts |
Posted - 2007-07-30 : 08:14:14
|
Hi AllI've had a search through the Forums, but can't seem to find a similar problem / solution to the issue I have, so would appreciate any help anyone could offer, as I'm pretty much stuck...I have an existing table (created from a query on another table), which includes the following columns and info:MMSINumber ReportingInterval PositionLost-------------------------------------------------------------0 20 01 30 01 170 01 30 02 50 02 40 02 180 02 160 03 30 03 150 03 170 03 150 03 110 0This information relates to multiple position 'reports' made by numerous entities over a period of time, with the 'MMSINumber' values indicating the individual entities in question. The information is ordered by Datetime (column not shown above). The 'PositionLost' column is populated by default with a value of '0' from the previous query (although this could obviously be altered to populate with NULL values on table creation).What I need to do is update the table to insert a tally / increment under the 'PositionLost' column, based on the following criteria:- The tally / increment to be calculated for each distinct value under 'MMSINumber'.- Default value for 'PositionLost' is 0.- If 'ReportingInterval' value is >= 100, then increment 'PositionLost' value by 1.- If 'ReportingInterval' value is < 100, then 'PositionLost' value equals the last 'PositionLost' value for that 'MMSINumber' value, or 0 if no other records for that 'MMSINumber' value are in the previous rows.The objective is to obtain an updated table with values looking like this:MMSINumber ReportingInterval PositionLost-------------------------------------------------------------0 20 01 30 01 170 11 30 12 50 02 40 02 180 12 160 23 30 03 150 13 170 23 150 33 110 4Now I thought a cursor might be the best way to undertake this (through fetching the individual rows into variables), but am obviously doing something (very) stupid here, as when the query is executed, the 'PositionLost' values in the table are all updated with a value of 4730 ! The portion of code I currently am trying to work with is:DECLARE MMSICursor CURSORFOR SELECT GISResults.MMSINumber, GISResults.ReportingInterval FROM GISResultsOPEN MMSICursorFETCH NEXT FROM MMSICursor INTO @MMSICounter, @IntervalCounterFETCH NEXT FROM MMSICursor INTO @MMSICounter2, @IntervalCounter2WHILE @@FETCH_STATUS = 0BEGIN IF ( @IntervalCounter >= 100 ) AND ( @MMSICounter = @MMSICounter2 ) BEGIN UPDATE GISResults SET @PositionLostCounter = GISResults.PositionLost = @PositionLostCounter + 1 SET @MMSICounter = @MMSICounter2 SET @IntervalCounter = @IntervalCounter2 FETCH NEXT FROM MMSICursor INTO @MMSICounter2, @IntervalCounter2 END IF ( @IntervalCounter < 100 ) AND ( @MMSICounter = @MMSICounter2 ) BEGIN UPDATE GISResults SET GISResults.PositionLost = @PositionLostCounter SET @MMSICounter = @MMSICounter2 SET @IntervalCounter = @IntervalCounter2 FETCH NEXT FROM MMSICursor INTO @MMSICounter2, @IntervalCounter2 END IF ( @MMSICounter <> @MMSICounter2 ) BEGIN SET @PositionLostCounter = 0 SET @MMSICounter = @MMSICounter2 SET @IntervalCounter = @IntervalCounter2 FETCH NEXT FROM MMSICursor INTO @MMSICounter2, @IntervalCounter2 ENDENDCLOSE MMSICursorDEALLOCATE MMSICursor There is currently no column set with a primary key, which I guess will have something to do with it, as I'll need to tell the system where to insert the values?Any help or pointers on this would be appreciated - apologies for the long-winded post!ThanksSteve |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-07-30 : 08:54:04
|
What defines the ORDER of records? The three column present can't be used to tell that.Do you have an IDENTITY or datetime column to define your order? E 12°55'05.25"N 56°04'39.16" |
 |
|
23Soul
Starting Member
3 Posts |
Posted - 2007-07-30 : 09:02:25
|
quote: Originally posted by Peso What defines the ORDER of records? The three column present can't be used to tell that.Do you have an IDENTITY or datetime column to define your order? E 12°55'05.25"N 56°04'39.16"
HiYes... as I mentioned in the original post (you might not have noticed, the post was a bit or a mind-blurt ), the information is ordered by Datetime, which is contained in a separate column (not shown in my example).CheersSteve |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-07-30 : 09:02:44
|
[code]-- Prepare sample dataDECLARE @Sample TABLE (ID INT IDENTITY PRIMARY KEY, MMSINumber INT, ReportingInterval INT, PositionLost INT)INSERT @SampleSELECT 0, 20, 0 UNION ALLSELECT 1, 30, 0 UNION ALLSELECT 1, 170, 0 UNION ALLSELECT 1, 30, 0 UNION ALLSELECT 2, 50, 0 UNION ALLSELECT 2, 40, 0 UNION ALLSELECT 2, 180, 0 UNION ALLSELECT 2, 160, 0 UNION ALLSELECT 3, 30, 0 UNION ALLSELECT 3, 150, 0 UNION ALLSELECT 3, 170, 0 UNION ALLSELECT 3, 150, 0 UNION ALLSELECT 3, 110, 0-- BeforeSELECT * FROM @Sample-- Stage the dataDECLARE @Number INT, @Lost INT SELECT @Number = MMSINumber, @Lost = 0FROM @SampleWHERE ID = 1UPDATE @SampleSET @Lost = PositionLost = CASE WHEN MMSINumber = @Number AND ReportingInterval >= 100 THEN @Lost + 1 WHEN MMSINumber = @Number AND ReportingInterval < 100 THEN @Lost ELSE 0 END, @Number = MMSINumber-- AfterSELECT * FROM @Sample[/code] E 12°55'05.25"N 56°04'39.16" |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-07-30 : 09:04:32
|
[code]-- Prepare sample dataCREATE TABLE #Sample ( dt DATETIME, MMSINumber INT, ReportingInterval INT, PositionLost INT )INSERT #SampleSELECT '20070601', 0, 20, 0 UNION ALLSELECT '20070602', 1, 30, 0 UNION ALLSELECT '20070604', 1, 170, 0 UNION ALLSELECT '20070606', 1, 30, 0 UNION ALLSELECT '20070401', 2, 50, 0 UNION ALLSELECT '20071231', 2, 40, 0 UNION ALLSELECT '20080101', 2, 180, 0 UNION ALLSELECT '20080601', 2, 160, 0 UNION ALLSELECT '20040229', 3, 30, 0 UNION ALLSELECT '20040301', 3, 150, 0 UNION ALLSELECT '20050906', 3, 170, 0 UNION ALLSELECT '20051231', 3, 150, 0 UNION ALLSELECT '20070730', 3, 110, 0CREATE CLUSTERED INDEX IX_Sample ON #Sample (MMSINumber, dt)-- BeforeSELECT * FROM #Sample-- Stage the dataDECLARE @Number INT, @Lost INT UPDATE #SampleSET @Lost = PositionLost = CASE WHEN @Number IS NULL THEN 0 WHEN MMSINumber = @Number AND ReportingInterval >= 100 THEN @Lost + 1 WHEN MMSINumber = @Number AND ReportingInterval < 100 THEN @Lost ELSE 0 END, @Number = MMSINumber-- AfterSELECT * FROM #SampleDROP TABLE #Sample[/code] E 12°55'05.25"N 56°04'39.16" |
 |
|
23Soul
Starting Member
3 Posts |
Posted - 2007-07-30 : 11:09:58
|
That's great - thanks for the assist.Guess I didn't need to go near a cursor at all then! |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-07-30 : 11:28:16
|
No, just add a proper clustered index, and go! E 12°55'05.25"N 56°04'39.16" |
 |
|
|
|
|
|
|