Home All Groups Group Topic Archive Search About

time-series calculation logic question

Author
23 Jun 2006 6:44 PM
GB
Hello,
I have a simple table of 2 columns: datadate ( datetime) like '2006-01-31'
and x (real).
I am trying to implement the following logic:

If x(t-1) > x(t-2) then Flag(t) = 1
If x(t-1) < x(t-2) then Flag(t) = 0
If x(t-1) = x(t-2) then Flag(t) = Flag(t-1)

So, t is datadate column value here.

I am trying to do that as:

SELECT DATEADD(MM,2,T2.datadate) as datadate,
Flag = (CASE
          WHEN T1.x > T2.x  THEN 1
          WHEN T1.x = T2.x  THEN (???)
          ELSE 0
     END)
FROM MyTable T1
LEFT OUTER JOIN MyTable T2
ON DATEADD(MM,1,T1.datadate) = DATEADD(MM,2,T2.datadate)

My question is : what I need to put instead of (???) ?

Thanks,
GB

Author
23 Jun 2006 8:20 PM
Alexander Kuznetsov
[Message not available]
Author
23 Jun 2006 9:07 PM
GB
This is the DDL:
create table MyTable (d datetime, x real)
insert into MyTable values('20060101', 15.75)
insert into MyTable values('20060201', 16.5)
insert into MyTable values('20060301', 16.5)
insert into MyTable values('20060401', 16.5)
insert into MyTable values('20060501', 16.5)
insert into MyTable values('20060601', 16.5)
insert into MyTable values('20060701', 16.0)
insert into MyTable values('20060901', 13.5)
insert into MyTable values('20061001', 13.)
insert into MyTable values('20061101', 12.)
insert into MyTable values('20061201', 11.5)
insert into MyTable values('20070101', 11.)

I need the output like this:
Datadate   Flag
------------------
20060301   1
20060401   1
20060501   1
20060601   1
20060701   1
20060901   0
20061001   0
20061101   0
20061201   0
20070101   0


Thanks,
GB
Show quote
"Alexander Kuznetsov" <AK_TIREDOFSPAM@hotmail.COM> wrote in message
news:1151094012.519391.205290@m73g2000cwd.googlegroups.com...
> your requirements are incomplete
>
> Consider the following original data (BTW next time please include DDL
> and DML as I did):
>
> create table t(d datetime, x float)
> insert into t values('20060101', 1.)
> insert into t values('20060201', 1.)
> insert into t values('20060301', 1.)
>
> It is not clear from your post what to select in this case.
>
Author
23 Jun 2006 9:37 PM
Alexander Kuznetsov
select * from(
select t1.d,
case
  when (select top 1 x from MyTable t2 where t2.d < t1.d and t2.x <>
t1.x) < t1.x
    then 1
  when (select top 1 x from MyTable t2 where t2.d < t1.d and t2.x <>
t1.x) > t1.x
    then 0
  else null
end md
from Mytable t1) t
where md is not null
Author
23 Jun 2006 9:40 PM
Alexander Kuznetsov
correction:

select * from(
select t1.d,
case
  when (select top 1 x from MyTable t2 where t2.d < t1.d and t2.x <>
t1.x order by d desc) < t1.x
    then 1
  when (select top 1 x from MyTable t2 where t2.d < t1.d and t2.x <>
t1.x order by d desc) > t1.x
    then 0
  else null
end md
from Mytable t1) t
where md is not null

I added "order by d desc" for both subqueries
Author
23 Jun 2006 10:13 PM
GB
Thanks!

Show quote
"Alexander Kuznetsov" <AK_TIREDOFSPAM@hotmail.COM> wrote in message
news:1151098806.238751.289540@c74g2000cwc.googlegroups.com...
> correction:
>
> select * from(
> select t1.d,
> case
>   when (select top 1 x from MyTable t2 where t2.d < t1.d and t2.x <>
> t1.x order by d desc) < t1.x
>     then 1
>   when (select top 1 x from MyTable t2 where t2.d < t1.d and t2.x <>
> t1.x order by d desc) > t1.x
>     then 0
>   else null
>  end md
> from Mytable t1) t
> where md is not null
>
> I added "order by d desc" for both subqueries
>
Author
25 Jun 2006 5:54 AM
Uri Dimant
GB
Assuming that 'd' is a PRIMARY KEY.

create table MyTable (d datetime, x real)

insert into MyTable values('20060101', 15.75)
insert into MyTable values('20060201', 16.5)
insert into MyTable values('20060301', 16.5)
insert into MyTable values('20060401', 16.5)
insert into MyTable values('20060501', 16.5)
insert into MyTable values('20060601', 16.5)
insert into MyTable values('20060701', 16.0)
insert into MyTable values('20060901', 13.5)
insert into MyTable values('20061001', 13.)
insert into MyTable values('20061101', 12.)
insert into MyTable values('20061201', 11.5)
insert into MyTable values('20070101', 11.)


select case when x<=x1 then 1 else 0 end
from
(
select * ,( select top 1 m.x from MyTable m where m.d>MyTable.d) as x1
from  MyTable
) as der



drop table MyTable
"GB" <v7v***@hotmail.com> wrote in message
news:hIZmg.77517$S61.8993@edtnps90...
Show quote
> Thanks!
>
> "Alexander Kuznetsov" <AK_TIREDOFSPAM@hotmail.COM> wrote in message
> news:1151098806.238751.289540@c74g2000cwc.googlegroups.com...
>> correction:
>>
>> select * from(
>> select t1.d,
>> case
>>   when (select top 1 x from MyTable t2 where t2.d < t1.d and t2.x <>
>> t1.x order by d desc) < t1.x
>>     then 1
>>   when (select top 1 x from MyTable t2 where t2.d < t1.d and t2.x <>
>> t1.x order by d desc) > t1.x
>>     then 0
>>   else null
>>  end md
>> from Mytable t1) t
>> where md is not null
>>
>> I added "order by d desc" for both subqueries
>>
>
>
Author
26 Jun 2006 1:31 PM
Alexander Kuznetsov
Uri,

> select case when x<=x1 then 1 else 0 end
> from
> (
> select * ,( select top 1 m.x from MyTable m where m.d>MyTable.d) as x1
>  from  MyTable
> ) as der
>

I agree that your query looks nicer than mine, thanks! Yet because
TOP(n) without an ORDER BY is unpredictable, I think your query should
be corrected as follows:

select * ,( select top 1 m.x from MyTable m where m.d>MyTable.d ORDER
BY D DESC) as x1

What do you think?
Author
25 Jun 2006 1:15 PM
--CELKO--
This is a good example of why time is modeled as a duration or as
changes, but not as static points.  Your model is always going to
require complex outer self-joins to get a simple fact about the delta
in your measurements because that fact is split over at least two rows
in the same table.  Why not store the whole fact in one row to start
with?  Then your query is trivial.

CREATE TABLE SampleDeltas
(sample_time DATETIME NOT NULL,
prev_measure REAL NOT NULL,
curr_measure REAL NOT NULL);

INSERT INTO SampleDeltas VALUES ('2006-01-01', 0.00, 15.75);
INSERT INTO SampleDeltas VALUES ('2006-02-01', 15.75, 16.5);
INSERT INTO SampleDeltas VALUES ('2006-03-01', 16.5, 16.5);
INSERT INTO SampleDeltas VALUES ('2006-04-01', 16.5, 16.5);
INSERT INTO SampleDeltas VALUES ('2006-05-01', 16.5, 16.5);
INSERT INTO SampleDeltas VALUES ('2006-06-01', 16.5, 16.5);
INSERT INTO SampleDeltas VALUES ('2006-07-01', 16.5, 16.0);
INSERT INTO SampleDeltas VALUES ('2006-09-01', 16.0, 13.5);
INSERT INTO SampleDeltas VALUES ('2006-10-01', 13.5, 13.0);
INSERT INTO SampleDeltas VALUES ('2006-11-01', 13.0, 12.0);
INSERT INTO SampleDeltas VALUES ('2006-12-01', 12.0, 11.5);
INSERT INTO SampleDeltas VALUES ('2007-01-01', 11.5, 11.0);

This is the table that you construct everytime on the fly at greater
and greater expense.

AddThis Social Bookmark Button