Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsFormsForms ProgrammingQueriesModules / DAO / VBAReports / PrintingMacrosDatabase DesignSecurityConversionImporting / LinkingSQL Server / ADPMultiuser / NetworkingReplicationSetup / ConfigurationDeveloper ToolkitsActiveX ControlsNew UsersGeneral 1General 2
Access DirectoryToolsTutorialsUser Groups
Related Topics
SQL ServerOther DB ProductsMS OfficeMore Topics ...

MS Access Forum / Queries / March 2006

Tip: Looking for answers? Try searching our database.

Finding the first LOCAL minimum in a time series

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
LStegman - 24 Mar 2006 09:00 GMT
I am tracking a variable for different subjects over time.  I want to find
the date and value of the FIRST local minimum, NOT the global minimum for
the subject.  

Here is some sample data:

ID     Value      Date
1      10          1/10/03
1      5            1/10/04
1      1            1/10/05
1      0.5         1/10/06
1      2            3/10/06
1      0.1         3/12/06
1      4            3/16/06

2      3            1/10/01
2      1            1/10/02
2      1            3/10/02
2      2            6/10/02.
2      0.2         5/10/03
2      5            6/3/04

I want a query that will give the following results:

ID     Value      Date
1       0.5        1/10/06
2      1            1/10/02

Any suggestions on how to do this with SQL only or does it require a
recursive script?
Duane Hookom - 24 Mar 2006 13:05 GMT
What do you mean by "different subjects"? There is no "subject" in your
data.
What do you mean by "FIRST local minimum"? There is no "local" in your data.
Why aren't
1      0.1         3/12/06
2      0.2         5/10/03
returned in your query?

Signature

Duane Hookom
MS Access MVP
--

>I am tracking a variable for different subjects over time.  I want to find
> the date and value of the FIRST local minimum, NOT the global minimum for
[quoted text clipped - 26 lines]
> Any suggestions on how to do this with SQL only or does it require a
> recursive script?
Gary Walter - 24 Mar 2006 15:59 GMT
Interesting...I wish I didn't have to
go into work....

I think this is like in calculus where
the truly interesting points of an
"messy" function are where the
slope changes (or especially where
the slope is zero).

so you find the "slope" by subtracting
the previous value for a specific ID
from the current value.

then pick out first record for an ID
(min date) that "slope"
goes from negative to zero (or positive).

I'm sorry I don't have time right now
to work thru some "gotchas" but I'd
start with query that subtracts previous
from current.

Actually..it might be better to subtract current
value from next value...

If no one has provided solution tonight
I will work on it.

good luck,

gary

> What do you mean by "different subjects"? There is no "subject" in your
> data.
[quoted text clipped - 35 lines]
>> Any suggestions on how to do this with SQL only or does it require a
>> recursive script?
Gary Walter - 24 Mar 2006 16:40 GMT
one "quick-and-dirty" solution:

I'm going to assume "tblStegman"
is name of your table and field names
do not use reserved words (changed
"Value" to "AValue" and "Date" to "ADate")

first query ("qryStegman1")

SELECT
tblStegman.ID,
tblStegman.AValue,
tblStegman.ADate,
(SELECT TOP 1 t1.AValue
FROM tblStegman As t1
WHERE
t1.ID = tblStegman.ID
AND
t1.ADate > tblStegman.ADate
ORDER BY t1.ADate) AS NextValue
FROM tblStegman
WHERE
((((SELECT TOP 1 t1.AValue
FROM tblStegman As t1
WHERE
t1.ID = tblStegman.ID
AND
t1.ADate > tblStegman.ADate
ORDER BY t1.ADate))>=[AValue]));

final query (based on first query):

SELECT
qS.ID,
qS.AValue,
qS.ADate
FROM qryStegman1 AS qS
WHERE
(((qS.ADate)=
(SELECT
Min(q.ADate)
From qryStegman1 As q
WHERE q.ID = qS.ID)))
GROUP BY qS.ID, qS.AValue, qS.ADate;

good luck,

gary

"Gary Walter"wrote"

> I think this is like in calculus where
> the truly interesting points of an
[quoted text clipped - 66 lines]
>>> Any suggestions on how to do this with SQL only or does it require a
>>> recursive script?
Gary Walter - 24 Mar 2006 17:55 GMT
Well..I'm already "very late," so
here be a "less-dirty" solution:

In the first query we bring 2 instances
of your table, aliasing one as "CurrentData"
and the other as "NextData." Using 2 copies
of a table is acommon way for handling
values from "adjacent rows."

What makes a row from NextData
the adjacent (next) row to a row in
CurrentData?

- the ID's need to match up.
- the ADate for NextData needs
  to be the earliest date in the table
  that is later than current date.

SELECT
CurrentData.ID,
CurrentData.AValue,
CurrentData.ADate,
NextData.AValue AS NextValue
FROM tblStegman AS CurrentData
INNER JOIN tblStegman AS NextData
ON CurrentData.ID = NextData.ID
WHERE
NextData.ADate =
(SELECT Min(t.Adate)
FROM tblStegman As t
WHERE t.ID = CurrentData.ID
AND
t.ADate > CurrentData.ADate);

from your example data, we'd get:

ID AValue ADate      NextValue
1       10    1/10/2003      5
1        5     1/10/2004     1
1        1     1/10/2005    0.5
1     0.5     1/10/2006      2
1        2     3/10/2006    0.1
1     0.1     3/12/2006      4
2        3     1/10/2001     1
2        1     1/10/2002      1
2        1     3/10/2002      2
2        2     6/10/2002    0.2
2     0.2     5/10/2003     5

if we only care about the rows
where next value >= current value
(where "slope" changes), then we
can add that criteria to the query above
(this is all predicated on my actually
understanding what you want...)

SELECT
CurrentData.ID,
CurrentData.AValue,
CurrentData.ADate,
NextData.AValue AS NextValue
FROM tblStegman AS CurrentData
INNER JOIN tblStegman AS NextData
ON CurrentData.ID = NextData.ID
WHERE
(NextData.AValue >= CurrentData.AValue)
AND
(NextData.ADate =
(SELECT Min(t.Adate)
FROM tblStegman As t
WHERE t.ID = CurrentData.ID
AND
t.ADate > CurrentData.ADate));

producing from your example data:

ID AValue ADate NextValue
1     0.5     1/10/2006     2
1     0.1     3/12/2006    4
2     1        1/10/2002    1
2     1        3/10/2002    2
2    0.2      5/10/2003   5

we can save this as "qryMins"
then final query simply picks out
the minimum date for each ID.

SELECT
qM.ID,
qM.AValue,
qM.ADate
FROM qryMins AS qM
WHERE
qM.ADate =
(SELECT MIN(q.ADate)
FROM qryMins As q
WHERE q.ID = qM.ID)
GROUP BY
qM.ID,
qM.AValue,
qM.ADate;

ID   AValue    ADate
1       0.5        1/10/2006
2       1           1/10/2002

I guess I'm really late now,
but this is less "dirty."

good luck,

gary

> I think this is like in calculus where
> the truly interesting points of an
[quoted text clipped - 66 lines]
>>> Any suggestions on how to do this with SQL only or does it require a
>>> recursive script?
Gary Walter - 24 Mar 2006 18:03 GMT
I don't know where that "group by" came from
(other than me 8-) )

this should work just fine thank you
for your final query....

SELECT
qM.ID,
qM.AValue,
qM.ADate
FROM qryMins AS qM
WHERE
qM.ADate =
(SELECT MIN(q.ADate)
FROM qryMins As q
WHERE q.ID = qM.ID);

> Well..I'm already "very late," so
> here be a "less-dirty" solution:
[quoted text clipped - 179 lines]
>>>> Any suggestions on how to do this with SQL only or does it require a
>>>> recursive script?
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.