SQL loop or alternative - sql-server

I am trying to gather a timestamp by day of turnover, it has to be run live so I cant store the data.
So the basic principal is that I need to see when a job was created, and then see if the delivery date is in a certain period. This then gives me a result. I then need to loop that for the total number of days in the month.
The code below works in a fashion in that It gathers the data, but it doesn't spit it out in 1 extract.
I need a procedure that will gather a time stamp function on various data
DECLARE #a int;
Set #a = 1
While #a <=31
Begin
Select
'2016-10-' + convert(varchar(3),#a),
Sum(mjob.Value) as value
From jobdetails as mjob
Where mjob.createDate <= '2016-10-' + convert(varchar(3),#a)
--this has to increment based on the #a
AND mjob.DeliveryTime between '2016-10-01' and '2016-11-01'--this stays the same throughout the given month
Set #a = #a +1
END

SUM() can also be used as a window function, with a <window frame preceding> to get cumulative sums.
At least on MS Sql Server 2012 and beyond.
select createDate,
sum(Value) over (partition by year(createDate), month(createDate) order by createDate rows unbounded preceding) AS CumulativeValue
from JobDetails
where CreateDate between '2016-10-01' and '2016-10-31'
and DeliveryTime between '2016-10-01' and '2016-11-01';

Related

can we use if condition for compare 2 dates and display the row in sql server

I have 2 dates column, one is current date and the one is user define date, I have to display the specific row when the user define date is 2days greater than current date.
In the below code I try to display the row, when both dates are equal. But I don't know how display the row in sql.
I have following Columns,
Rid
DateTime (User define date and time)
Reminder
Description
CRDateTime (current date and time)
I have to set 3 condition.
if both dates are equal means that should be display,
if DateTime is 2 days before CRDate means I have to display that row,
if DateTime is 1 day before the CRdate means I have to display that row.
declare DateTime as datetime1;
select RId if CAST (DateTime as date) =CAST (#CRDateTime as date)
The IF...ELSE statement is a control-flow statement that allows you to execute or skip a statement block based on a specified condition.
For example:
IF Boolean_expression
BEGIN
-- Statement block executes when the Boolean expression is TRUE
END
ELSE
BEGIN
-- Statement block executes when the Boolean expression is FALSE
END
If you want to check something in your SQL Statements you should use the where clause.
It could be looking like:
SELECT * FROM `[YOUR_TABLE_NAME]` WHERE `DateTime` = `CRDateTime`
If you want to check the date in a 2 Day decade you can use the SQL DATEADD Function.
It lookse like:
SELECT DATEADD(day, +1, '2017/08/25') AS DateAdd;
Resault of this code is 2017/08/26
In your case it looks like this:
SELECT RId where DATEADD(day, +2, DateTime) = CRDateTime
--- EDIT SECTION: ---
EDIT 1:
All in one you can use this code here:
SELECT RId WHERE
`DateTime` = `CRDateTime` OR
DATEADD(day, +1, DateTime) = CRDateTime OR
DATEADD(day, +2, DateTime) = CRDateTime
As I understand you basically want to show all the records with in range of 2 days.
SELECT RId, DateTime, Reminder, Description, CRDateTime
WHERE CRDateTime BETWEEN DATETIME AND DATEADD(day, +2, DateTime)
Or you may try this
SELECT RId, DateTime, Reminder, Description, CRDateTime
WHERE DateTime BETWEEN DATEADD(day, -2, CRDateTime) AND CRDateTime
The question isn't clear. I assume the actual question is how to filter a table's rows between two dates.
Filtering in SQL (in any product) is the job of the WHERE clause, not IF. You can use the BETWEEN clause to select values in a range.
If both the table field and the query parameter are date variables, the query is easy :
CREATE TABLE table1
(
RId int PRIMARY KEY,
DateField date,
INDEX IX_Table1_Date (DateField)
)
declare #dateParam date='20190801';
SELECT RId
FROM table1
WHERE DateField BETWEEN dateadd(day,-2,#dateParam) AND #DateParam
This query will take advantage of the IX_Table1_Date index to speed up the search. Typically, applying any kind of function on a table field prevents the query engine from using any index that includes that field simply because the values stored in the index have no relation to the function's result.
If you use the date parameter to be the current date, just assign GETDATE() to it.
declare #dateParam date=GETDATE();
If the field isn't a date, you can cast it to date and still get a fast range query, because the query engine is fast enough to convert the cast to a range query.
SELECT RId
FROM table1
WHERE cast(DateField as date) BETWEEN dateadd(day,-2,#dateParam) AND #DateParam
If DateField is not a date-related type, eg it's a varchar, a) that's a serious bug and b) the server won't be able to use any indexes.
Casting the parameter values won't affect performance as they actual values are calculated before the query starts executing. The query becomes quite noisy though :
declare #dateParam datetime='20190801'
SELECT RId
FROM table1
WHERE cast(DateField as date)
BETWEEN dateadd(day,-2,cast(#dateParam as date)) AND cast(#DateParam as date)
That's why it's better to use the correct type for parameters

Make chart gaps in ZingChart when missing dates in dynamically loaded data?

I have been using ColdFusion 2016 and ZingCharts (bundled) to dynamically create charts using SQL Server, with a time series on the X axis. When there are time gaps I would like the line chart to also show a gap, but instead the line is continuous and plots each datapoint consecutively.
A pic of the chart the way it is plotting now, you can see there is no 'gap' between the Oct 29 and March dates, the data just run together:
My data are generally in 15min increments, but there are stretches of time (days or months) where there are gaps in the timeseries and data. I contacted ZingCharts to ask if there was some kind of style tag that controls whether the dates are displayed consecutively or with gaps and there is not. It's something that has to be manipulated at the data-level. If my data were hardcoded I would have to add null values so that the charts would plot with gaps in the timeseries, but my charts are dynamic (a user can choose any number of 7 parameters to add to the chart for a date range they choose). I have found information on how to solve this for hardcoded data, but I'm looking for ideas for solutions for dynamically loaded data/series. I have also found information on a deprecated coldfusion tag for the XML file, isInterpolated="false", but that's no longer an option.
My question is what is the best way to solve this? I found some information about creating a calendar table in SQL Server and unioning that with the table(s) providing the data so that all datetimes would be filled. I was wondering if there's another approach that I'm not thinking of? Thanks for any help, I'm very new at all of this.
Update: Here is the current query for the data, which is a bit complicated. It pulls "Nth" rows based on how many parameters (7 available) are selected and how many days are in the date range:
SELECT
distinct
datepart(year, t.sample_date) as [year]
,datepart(month, t.sample_date) as [month]
,datepart(day, t.sample_date) as [day]
,datepart(hour, t.sample_time) as [hr]
,datepart(minute, t.sample_time) as [min]
,convert(varchar(10), t.sample_date, 1) + ' ' +
RIGHT('0' + CONVERT([varchar](2), DATEPART(HOUR, t.sample_time)), 2) + ':' +
RIGHT('0' + CONVERT([varchar](2), DATEPART(MINUTE, t.sample_time)), 2) AS [datetime]
,t.stationdesc
<cfif isDefined("form.parameter") and ListFindNoCase(form.parameter, "salinity")>,ROUND(t.salinity,1) as salinity</cfif>
<!---plus 6 more parameters--->
FROM (
SELECT
[sample_date]
,sample_time
,stationdesc
<cfif isDefined("form.parameter") and ListFindNoCase(form.parameter, "salinity") >,salinity</cfif>
<!---plus 6 more parameters--->
, row_number() OVER (ORDER BY streamcode) AS rownum
FROM MyUnionizedTables
WHERE stationdesc = (<cfqueryparam value="#form.station#" cfsqltype="cf_sql_varchar">)
AND [sample_date] BETWEEN (<cfqueryparam value='#Form.StartDate#' cfsqltype="cf_sql_date">)
AND (<cfqueryparam value='#Form.EndDate#' cfsqltype="cf_sql_date">)
<cfif isDefined("form.parameter") and ListFindNoCase(form.parameter, "salinity")>and salinity > -25 and salinity <40 and salinity is not NULL </cfif>
<!---plus 6 more parameters--->
GROUP BY sample_date, sample_time, stationdesc, streamcode
<cfif isDefined("form.parameter") and ListFindNoCase(form.parameter, "salinity")>,salinity</cfif>
<!---plus 6 more parameters--->
) AS t
WHERE <!---returning Nth row when record sets (count of days between dates selected) are long--->
<cfif IsDefined("form.station") AND IsDefined("form.parameter") AND #ParamCount# LTE 3 AND form.station eq 'Coastal Bays - Public Landing' and #ctdays# gte 10> t.rownum % 64 = 0
<cfelseif IsDefined("form.parameter") AND #ParamCount# LTE 3 AND #ctDays# gte '5840'> t.rownum % 64 = 0
<!---plus lots more elseifs--->
<cfelseif IsDefined("form.parameter") AND #ParamCount# GTE 7 AND #ctDays# gte '350'> t.rownum % 8 = 0
<cfelse>t.rownum % 1 = 0</cfif>
ORDER BY
datepart(year, t.sample_date)
,datepart(month, t.sample_date)
,datepart(day, t.sample_date)
,datepart(hour, t.sample_time)
,datepart(minute, t.sample_time)
SECOND UPDATE (after Leigh's link to query on GitHub):
So I'd actually been working on a similar query to the one Leigh posted based on the "CTE Expression" section here. I switched to trying to work with her version, which is below.
I don't have write edits, so I'm working with an existing table. MyDataTable has ~ 21mil rows, with a separate sample_date(datetime) and sample_time(datetime) [the dates and times are a PITA - b/c of the instruments and the way these data are remotely telemetered we get a datetime column with a 'good date' but a bogus timevalue that we call 'sample_date', and then a separate datetime column called 'sample_time' with a bogus date and a 'good time'.] There are 125 stations, each with data (for example, temperature) from different starting and ending dates/times, beginning in 2001 through present. So I need to fill date/time gaps for 125 different stations with differing gaps of time, that are normally in 15min increments.
--- simulate main table(s)
--CREATE TABLE MyDataTable ( sample_date datetime, sample_time datetime, stationdesc nvarchar, wtemp float)
--- generate all dates within this range
DECLARE #startDate datetime
DECLARE #maxDate datetime
SET #startDate = '2015-01-01'
SET #maxDate = '2016-12-31'
--- get MISSING dates
;WITH missingDates AS
(
SELECT DATEADD(day,1,#startDate) AS TheDate
UNION ALL
SELECT DATEADD(day,1, TheDate)
FROM missingDates
WHERE TheDate < #maxDate
)
SELECT *
--[wtemp]
-- ,[stationdesc]
-- ,[TIMEVALUE]
FROM missingDates mi LEFT JOIN MyDataTable t ON t.sample_date = mi.TheDate
WHERE t.sample_date IS NULL
--and stationdesc = 'Back River - Lynch Point'
--ORDER BY timevalue
OPTION (MAXRECURSION 0)
When I run this query as-is I get only 17 rows of data. TheDate column lists datetimes with dates 12/15-12/31/16 and all times are 00:00:00.000. Query takes 49s.
Meanwhile, my coworker and I have been working on alternate methods.
--Putting data from only 1 station from our big datatable into the new testtable called '_testdatatable'
SELECT station, sample_date, sample_time, wtemp, streamcode, stationdesc, TIMEVALUE
INTO _testdatatable
FROM MyBigDataTable
WHERE (stationdesc = 'Back River')
order by [sample_date],[sample_time]
--Next, make a new table [_testdatatableGap] with all time values in 15min increments from a datetime table we made
SELECT [wtemp]=null
,[streamcode]='ABC1234'
,[stationdesc]= 'Back River'
,[TIMEVALUE]
into [tide].[dbo].[_testdatatableGap]
FROM DateTimeTable
WHERE (TIMEVALUE BETWEEN '4/19/2014' AND getdate())
--Then, get the missing dates from the Gap table and put into the testdatatable
INSERT into [_testdatatable]
( [wtemp]
,[streamcode]
,[stationdesc]
,[TIMEVALUE]
)
(SELECT
[wtemp]=null -- needs this for except to work
,
[streamcode]
,[stationdesc]
,
[TIMEVALUE]
FROM [_testdatatableGap]
EXCEPT
SELECT
[wtemp]=null -- needs this for except to work
,
[streamcode]
,[stationdesc]
,
[TIMEVALUE]
FROM [_testdatatable])
This method worked to create a table with all the 15min increments in date/time, which resulted in a correctly drawn chart (below). However, we don't know how to scale this up to the full 125 station full data table without making multiple tables.
After working through several suggestions, and a lot of research, trial and error I think I’ve solved my problem. I need to work on my additional complication of sometimes needing to reduce the volume of data returned and graphed, but that part is sort of outside the realm of my original question.
The short version of my answer is:
Made a table view of MyBigDataTable with an additional column which is a
datetime column called “TIMEVALUE”.
Made a big permanent datetime calendar table with the datetime column called the same:
“TIMEVALUE”.
I then developed a set of SQL queries that
(a) gather data from MyBigDataTable and put it into a #temptable, and
(b) also gathers datetimes from the calendar table and puts it into the same #temptable.
Then,
(c) because now there will sometimes be 2 datetime rows, one with data and one
with nulls, I run a query to only keep the row with data if there
are 2 rows of matching datetime and station. This data can then be charted.
This is all now written dynamically in my .cfm page, station, date
range and parameters are chosen by a user and a chart is now
successfully drawn with correct ‘gaps’ in the datetimes for times of
missing data.
Here’s SQL (here, limited to only 1 parameter, but I have 8):
--Step 1. Check if the temptable exists, if it does then delete it
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
BEGIN
DROP TABLE #TempTable
END
;
--Step 2. Create the temptable with data from the parameters, station and dates selected on the .cfm
SET NOCOUNT ON
SELECT
timevalue
,stationdesc
,wtemp
INTO #TempTable
FROM MyBigDataTable
WHERE
stationdesc = 'Station01'
and [timevalue] BETWEEN '5/29/2014' AND '10/01/2016'
GROUP BY
TIMEVALUE
,stationdesc
,wtemp
;
--Step 3. Now select datetimes from a big calendar table, and set stationdesc to the selected station,
--and rest of parameters to null. And do this for the same selected date range
INSERT INTO #TempTable
SELECT
[TIMEVALUE]
,[stationdesc]= 'Station01'
,wtemp=null
FROM MyDatetimeCalendarTable
WHERE [timevalue] BETWEEN '5/29/2014' AND '10/01/2016'
;
--Step 4. Run query on the temptable to gather data for chart, but b/c sometimes there will be 2 rows with the same datetime and station but one with data and one with nulls, this query only gathers the row with data if there are 2 rows with matching datetime and station
SELECT distinct *
FROM #TempTable a
WHERE
wtemp is not null or
wtemp is null and
not exists(
SELECT * FROM #TempTable b
WHERE a.timevalue=b.timevalue
and a.stationdesc=b.stationdesc and b.wtemp is not null)
ORDER BY timevalue
;
I need to fully test it and make some amendments, but I think this satisfies the requirements of an answer, because so far it's doing what I need it to do. Thank you to #Leigh and #Dan Bracuk for their wisdom (and patience!)

how to calculate all previous datas sum of a sql column on a date range report

I have a crystal report with debit credit columns using a sql command. This report contains a date to date filtering parameters. So the problem is if i filter the report to date range i need all the previous data sum using a sql command.
Select SUM(CAST(debit as DECIMAL(9,2)))- SUM(CAST(credit as DECIMAL(9,2)))
from sum_balance
where sum_date < sum_date
this is my code but i can't get the result from it. (e.g. : if the report starting from 2014-07-01 then i need the sum(debit - credit) of all previous data before 2014-07-01). Can anyone help me to find a solution for this. THe main thing is to add a brought forward balance using sql command on first row. If it is null then it should be 0.00.
Here is your sample table
CREATE TABLE #TEMP(DEBIT NUMERIC(20,2),CREDIT NUMERIC(20,2),DT VARCHAR(20))
INSERT INTO #TEMP
SELECT 1000 DEBIT,500 CREDIT,'2014-11-27' DT
UNION ALL
SELECT 2000 DEBIT,700 CREDIT,'2014-11-28' DT
UNION ALL
SELECT 3000 DEBIT,900 CREDIT,'2014-11-29' DT
I am updating answer for your updated requirement
QUERY 1
This will bring the total till current date, ie, for 2014-11-28 the amount will be (1000+2000)-(500+700), for 2014-11-29 the amount will be (1000+2000+3000)-(500+700+900)
SELECT T2.DEBIT,T2.CREDIT,T2.sum_date,
(SELECT SUM(DEBIT)-SUM(CREDIT) FROM sum_balance WHERE sum_date <= CAST(T2.sum_date AS DATE))
AMOUNT
FROM sum_balance T2
SQL FIDDLE
QUERY 2
This will bring the sum till previous day, that will be opening balance for today's date ie, for 2014-11-29 the amount will be (1000+2000)-(500+700). For easy understanding I have added the previous column also.
;WITH CTE AS
(
SELECT ROW_NUMBER() OVER(ORDER BY CAST(T2.sum_date AS DATE))RNO,
T2.DEBIT,T2.CREDIT,T2.sum_date,
ISNULL((SELECT SUM(DEBIT)-SUM(CREDIT) FROM sum_balance WHERE sum_date <= CAST(T2.sum_date AS DATE)),0)
AMOUNT
FROM sum_balance T2
)
SELECT C1.*,ISNULL(C2.AMOUNT,0) CARRYFORWARD
FROM CTE C1
LEFT JOIN CTE C2 ON C1.RNO=C2.RNO+1
SQL FIDDLE
You can use QUERY 2 and you will get opening balance till previous day in CARRYFORWARD column.
Please leave a message or comment for any changes.
When you need records previous than some date then you need to have that comparision date so that records can be extracted.
Your where clause where sum_date < sum_date won't work this way either you change the right side comparision operator in query or create a parameter in crystal so that user can enter the required end date during run time.
option 1:
E.g: where sum_date < currentdate
option 2:
Create a parameter and declare it in Record Selection Formula in crystal reports so that formed query will be something like
where sum_date < 2014-07-01
You can try this:-
SELECT SUM(CAST(debit as DECIMAL(9,2)))- SUM(CAST(credit as DECIMAL(9,2)))
FROM sum_balance
WHERE sum_date < (Select Max(sum_date) FROM sum_balance)

Query to create records between two dates

I have a table with the following fields (among others)
TagID
TagType
EventDate
EventType
EventType can be populated with "Passed Inspection", "Failed Inspection" or "Repaired" (there are actually many others, but simplifies to this for my issue)
Tags can go many months between a failed inspection and the ultimate repair... in this state they are deemed to be "awaiting repair". Tags are still inspected each month even after they have been identified as having failed. (and just to be clear, a “failed inspection” doesn’t mean the item being inspected doesn’t work at all… it still works, just not at 100% capacity…which is why we still do inspections on it).
I need to create a query that counts, by TagType, Month and Year the number of Tags that are awaiting repair. The end result table would look like this, for example
TagType EventMonth EventYear CountofTagID
xyz 1 2011 3
abc 1 2011 2
xyz 2 2011 2>>>>>>>>>>>>indicating a repair had been made since 1/2011
abc 2 2011 2
and so on
The "awaiting repair" status should be assessed on the last day of the month
This is totally baffling me...
One thought that I had was to develop a query that returned:
TagID,
TagType,
FailedInspectionDate, and
NextRepairDate,
then try and do something that stepped thru the months in between the two dates, but that seems wildly inefficient.
Any help would be much appreciated.
Update
A little more research, and a break from the problem to think about it differently gave me the following approach. I'm sure its not efficient or elegant, but it works. Comments to improve would be appreciated.
declare #counter int
declare #FirstRepair date
declare #CountMonths as int
set #FirstRepair = (<Select statement to find first repair across all records>)
set #CountMonths = (<select statement to find the number of months between the first repair across all records and today>)
--clear out the scratch table
delete from dbo.tblMonthEndDate
set #counter=0
while #counter <=#CountMonths --fill the scratch table with the date of the last day of every month from the #FirstRepair till today
begin
insert into dbo.tblMonthEndDate(monthenddate) select dbo.lastofmonth(dateadd(m,#counter, #FirstRepair))
set #counter = #counter+1
end
--set up a CTE to get a cross join between the scratch table and the view that has the associated first Failed Inspection and Repair
;with Drepairs_CTE (FacilityID, TagNumber, CompType, EventDate)
AS
(
SELECT dbo.vwDelayedRepairWithRepair.FacilityID, dbo.vwDelayedRepairWithRepair.TagNumber, dbo.vwDelayedRepairWithRepair.CompType,
dbo.tblMonthEndDate.MonthEndDate
FROM dbo.vwDelayedRepairWithRepair INNER JOIN
dbo.tblMonthEndDate ON dbo.vwDelayedRepairWithRepair.EventDate <= dbo.tblMonthEndDate.MonthEndDate AND
dbo.vwDelayedRepairWithRepair.RepairDate >= dbo.tblMonthEndDate.MonthEndDate
)
--use the CTE to build the final table I want
Select FacilityID, CompType, Count(TagNumber), MONTH(EventDate), YEAR(EventDate), 'zzz' as EventLabel
FROM Drepairs_CTE
GROUP BY FacilityID, CompType, MONTH(EventDate), YEAR(EventDate)`
Result set ultimately looks like this:
FacilityID CompType Count Month Year Label
1 xyz 2 1 2010 zzz
1 xyz 1 2 2010 zzz
1 xyz 1 7 2009 zzz
Here is a recursive CTE which generates table of last dates of months in interval starting with minimum date in repair table and ending with maximum date.
;with tableOfDates as (
-- First generation returns last day of month of first date in repair database
-- and maximum date
select dateadd (m, datediff (m, 0, min(eventDate)) + 1, 0) - 1 startDate,
max(eventDate) endDate
from vwDelayedRepairWithRepair
union all
-- Last day of next month
select dateadd (m, datediff (m, 0, startDate) + 2, 0) - 1,
endDate
from tableOfDates
where startDate <= endDate
)
select *
from tableOfDates
-- If you change the CTE,
-- Set this to reasonable number of months
-- to prevent recursion problems. 0 means no limit.
option (maxrecursion 0)
EndDate column from tableOfDates is to be ignored, as it serves as upper bound only. If you create UDF which returns all the dates in an interval, omit endDate in select list or remove it from CTE and replace with a parameter.
Sql Fiddle playground is here.

SQL Server best way to calculate datediff between current row and next row?

I've got the following rough structure:
Object -> Object Revisions -> Data
The Data can be shared between several Objects.
What I'm trying to do is clean out old Object Revisions. I want to keep the first, active, and a spread of revisions so that the last change for a time period is kept. The Data might be changed a lot over the course of 2 days then left alone for months, so I want to keep the last revision before the changes started and the end change of the new set.
I'm currently using a cursor and temp table to hold the IDs and date between changes so I can select out the low hanging fruit to get rid of. This means using #LastID, #LastDate, updates and inserts to the temp table, etc...
Is there an easier/better way to calculate the date difference between the current row and the next row in my initial result set without using a cursor and temp table?
I'm on sql server 2000, but would be interested in any new features of 2005, 2008 that could help with this as well.
Here is example SQL. If you have an Identity column, you can use this instead of "ActivityDate".
SELECT DATEDIFF(HOUR, prev.ActivityDate, curr.ActivityDate)
FROM MyTable curr
JOIN MyTable prev
ON prev.ObjectID = curr.ObjectID
WHERE prev.ActivityDate =
(SELECT MAX(maxtbl.ActivityDate)
FROM MyTable maxtbl
WHERE maxtbl.ObjectID = curr.ObjectID
AND maxtbl.ActivityDate < curr.ActivityDate)
I could remove "prev", but have it there assuming you need IDs from it for deleting.
If the identity column is sequential you can use this approach:
SELECT curr.*, DATEDIFF(MINUTE, prev.EventDateTime,curr.EventDateTime) Duration FROM DWLog curr join DWLog prev on prev.EventID = curr.EventID - 1
Hrmm, interesting challenge. I think you can do it without a self-join if you use the new-to-2005 pivot functionality.
Here's what I've got so far, I wanted to give this a little more time before accepting an answer.
DECLARE #IDs TABLE
(
ID int ,
DateBetween int
)
DECLARE #OID int
SET #OID = 6150
-- Grab the revisions, calc the datediff, and insert into temp table var.
INSERT #IDs
SELECT ID,
DATEDIFF(dd,
(SELECT MAX(ActiveDate)
FROM ObjectRevisionHistory
WHERE ObjectID=#OID AND
ActiveDate < ORH.ActiveDate), ActiveDate)
FROM ObjectRevisionHistory ORH
WHERE ObjectID=#OID
-- Hard set DateBetween for special case revisions to always keep
UPDATE #IDs SET DateBetween = 1000 WHERE ID=(SELECT MIN(ID) FROM #IDs)
UPDATE #IDs SET DateBetween = 1000 WHERE ID=(SELECT MAX(ID) FROM #IDs)
UPDATE #IDs SET DateBetween = 1000
WHERE ID=(SELECT ID
FROM ObjectRevisionHistory
WHERE ObjectID=#OID AND Active=1)
-- Select out IDs for however I need them
SELECT * FROM #IDs
SELECT * FROM #IDs WHERE DateBetween < 2
SELECT * FROM #IDs WHERE DateBetween > 2
I'm looking to extend this so that I can keep at maximum so many revisions, and prune off the older ones while still keeping the first, last, and active. Should be easy enough through select top and order by clauses, um... and tossing in ActiveDate into the temp table.
I got Peter's example to work, but took that and modified it into a subselect. I messed around with both and the sql trace shows the subselect doing less reads. But it does work and I'll vote him up when I get my rep high enough.

Resources