 |
|
 |
|
Next: strange type conversion error with datetime...
|
| Author |
Message |
External

Since: Dec 21, 2006 Posts: 7
|
(Msg. 1) Posted: Thu Dec 21, 2006 9:46 pm
Post subject: Detecting value changes and grouping by them Archived from groups: microsoft>public>sqlserver>programming (more info?)
|
|
|
Hello,
I was wondering if anyone can help me with a problem I have. I have a
program (beyond my control) that constantly posts to a table the current
value of a set of parameters identified by name. I need to query it and
return for a given parameter and start\end times which values it had
between those times and the minimum and maximum times for each value.
To clarify, suppose I have the following table:
fName fTime fValue
----- ----- ------
Par2 1/1/2006 00:00 9
Par2 1/1/2006 00:01 9
Par2 1/1/2006 00:02 5
Par2 1/1/2006 00:03 5
Par2 1/1/2006 00:04 5
Par2 1/1/2006 00:05 3
Par1 1/1/2006 00:00 1
Par1 1/1/2006 00:01 1
Par1 1/1/2006 00:02 1
Par1 1/1/2006 00:03 1
Par1 1/1/2006 00:04 2
Par1 1/1/2006 00:05 2
Par1 1/1/2006 00:06 2
Par1 1/1/2006 00:07 2
Par1 1/1/2006 00:08 3
Par1 1/1/2006 00:09 3
Par1 1/1/2006 00:10 1
Par1 1/1/2006 00:11 2
Par1 1/1/2006 00:12 2
Par1 1/1/2006 00:13 4
Par1 1/1/2006 00:14 4
Par1 1/1/2006 00:15 4
For the parameter "Par1" and the time range "1/1/2006 00:05" to
"1/1/2006 00:14" I run the following query:
SELECT Min(fTime) AS FromTime, Max(fTime) AS ToTime, fValue AS Lbl
FROM tParams
WHERE (fName = 'Par1')
GROUP BY fName, fValue
HAVING (Min(fTime) <= '2006-1-1 00:14')
AND (Max(fTime) >= '2006-1-1 00:05')
And get the following result:
FromTime ToTime Lbl
-------- ------ ---
1/1/2006 00:04 1/1/2006 00:12 2
1/1/2006 00:08 1/1/2006 00:09 3
1/1/2006 00:00 1/1/2006 00:10 1
1/1/2006 00:13 1/1/2006 00:15 4
What I'm actually trying to get is:
FromTime ToTime Lbl
-------- ------ ---
1/1/2006 00:04 1/1/2006 00:07 2
1/1/2006 00:08 1/1/2006 00:09 3
1/1/2006 00:10 1/1/2006 00:10 1
1/1/2006 00:11 1/1/2006 00:12 2
1/1/2006 00:13 1/1/2006 00:15 4
That is, I want to detect all consecutive sequences of the same fValue
that intersect with the dates I requested (for the given fName) and
output the start-time and end-time of each sequence. Is there any way to
do so without resorting to client-side programming?
Thanks >> Stay informed about: Detecting value changes and grouping by them |
|
| Back to top |
|
 |  |
External

Since: Feb 07, 2006 Posts: 80
|
(Msg. 2) Posted: Thu Dec 21, 2006 9:46 pm
Post subject: Re: Detecting value changes and grouping by them [Login to view extended thread Info.] Archived from groups: per prev. post (more info?)
|
|
|
Using SQL Server 2005, you can do this (uses a difference of ranks)
set nocount on
create table tParams(fName char(4),fTime datetime,fValue int)
insert into tParams(fName ,fTime ,fValue)
select 'Par2' , '1/1/2006 00:00' , 9 union all
select 'Par2' , '1/1/2006 00:01' , 9 union all
select 'Par2' , '1/1/2006 00:02' , 5 union all
select 'Par2' , '1/1/2006 00:03' , 5 union all
select 'Par2' , '1/1/2006 00:04' , 5 union all
select 'Par2' , '1/1/2006 00:05' , 3 union all
select 'Par1' , '1/1/2006 00:00' , 1 union all
select 'Par1' , '1/1/2006 00:01' , 1 union all
select 'Par1' , '1/1/2006 00:02' , 1 union all
select 'Par1' , '1/1/2006 00:03' , 1 union all
select 'Par1' , '1/1/2006 00:04' , 2 union all
select 'Par1' , '1/1/2006 00:05' , 2 union all
select 'Par1' , '1/1/2006 00:06' , 2 union all
select 'Par1' , '1/1/2006 00:07' , 2 union all
select 'Par1' , '1/1/2006 00:08' , 3 union all
select 'Par1' , '1/1/2006 00:09' , 3 union all
select 'Par1' , '1/1/2006 00:10' , 1 union all
select 'Par1' , '1/1/2006 00:11' , 2 union all
select 'Par1' , '1/1/2006 00:12' , 2 union all
select 'Par1' , '1/1/2006 00:13' , 4 union all
select 'Par1' , '1/1/2006 00:14' , 4 union all
select 'Par1' , '1/1/2006 00:15' , 4 ;
with cte(fName,fTime,fValue,rn)
as (select fName,
fTime,
fValue,
rank() over(partition by fName order by fTime)-
rank() over(partition by fName,fValue order by fTime)
from tParams)
select min(fTime) as FromTime,
max(fTime) as ToTime,
fValue as Lbl
from cte
where fName = 'Par1'
group by fName,fValue,Rn
having (min(fTime) <= '2006-1-1 00:14')
and (max(fTime) >= '2006-1-1 00:05')
order by FromTime
Note that this is also possible with SQL Server 2000, but is a bit more
complex >> Stay informed about: Detecting value changes and grouping by them |
|
| Back to top |
|
 |  |
External

Since: Feb 07, 2006 Posts: 80
|
(Msg. 3) Posted: Thu Dec 21, 2006 9:46 pm
Post subject: Re: Detecting value changes and grouping by them [Login to view extended thread Info.] Archived from groups: per prev. post (more info?)
|
|
|
Here's a SQL Server 2000 version to try, not sure how well it will
perform.
select min(fTime) as FromTime,
max(fTime) as ToTime,
fValue as Lbl
from (select t.fName,
t.fTime,
t.fValue,
(select count(*)
from tParams t2
where t2.fName=t.fName
and t2.fTime<=t.fTime)-
(select count(*)
from tParams t2
where t2.fName=t.fName
and t2.fValue=t.fValue
and t2.fTime<=t.fTime)
from tParams t
where t.fName = 'Par1') as X(fName,fTime,fValue,rn)
group by fName,fValue,Rn
having (min(fTime) <= '2006-1-1 00:14')
and (max(fTime) >= '2006-1-1 00:05')
order by FromTime >> Stay informed about: Detecting value changes and grouping by them |
|
| Back to top |
|
 |  |
External

Since: Sep 29, 2006 Posts: 239
|
(Msg. 4) Posted: Thu Dec 21, 2006 9:46 pm
Post subject: Re: Detecting value changes and grouping by them [Login to view extended thread Info.] Archived from groups: per prev. post (more info?)
|
|
|
Zero One wrote:
> Hello,
>
> I was wondering if anyone can help me with a problem I have. I have a
> program (beyond my control) that constantly posts to a table the current
> value of a set of parameters identified by name. I need to query it and
> return for a given parameter and start\end times which values it had
> between those times and the minimum and maximum times for each value.
>
> To clarify, suppose I have the following table:
>
> fName fTime fValue
> ----- ----- ------
> Par2 1/1/2006 00:00 9
> Par2 1/1/2006 00:01 9
> Par2 1/1/2006 00:02 5
> Par2 1/1/2006 00:03 5
> Par2 1/1/2006 00:04 5
> Par2 1/1/2006 00:05 3
> Par1 1/1/2006 00:00 1
> Par1 1/1/2006 00:01 1
> Par1 1/1/2006 00:02 1
> Par1 1/1/2006 00:03 1
> Par1 1/1/2006 00:04 2
> Par1 1/1/2006 00:05 2
> Par1 1/1/2006 00:06 2
> Par1 1/1/2006 00:07 2
> Par1 1/1/2006 00:08 3
> Par1 1/1/2006 00:09 3
> Par1 1/1/2006 00:10 1
> Par1 1/1/2006 00:11 2
> Par1 1/1/2006 00:12 2
> Par1 1/1/2006 00:13 4
> Par1 1/1/2006 00:14 4
> Par1 1/1/2006 00:15 4
>
> For the parameter "Par1" and the time range "1/1/2006 00:05" to
> "1/1/2006 00:14" I run the following query:
>
> SELECT Min(fTime) AS FromTime, Max(fTime) AS ToTime, fValue AS Lbl
> FROM tParams
> WHERE (fName = 'Par1')
> GROUP BY fName, fValue
> HAVING (Min(fTime) <= '2006-1-1 00:14')
> AND (Max(fTime) >= '2006-1-1 00:05')
>
> And get the following result:
>
> FromTime ToTime Lbl
> -------- ------ ---
> 1/1/2006 00:04 1/1/2006 00:12 2
> 1/1/2006 00:08 1/1/2006 00:09 3
> 1/1/2006 00:00 1/1/2006 00:10 1
> 1/1/2006 00:13 1/1/2006 00:15 4
>
> What I'm actually trying to get is:
>
> FromTime ToTime Lbl
> -------- ------ ---
> 1/1/2006 00:04 1/1/2006 00:07 2
> 1/1/2006 00:08 1/1/2006 00:09 3
> 1/1/2006 00:10 1/1/2006 00:10 1
> 1/1/2006 00:11 1/1/2006 00:12 2
> 1/1/2006 00:13 1/1/2006 00:15 4
>
> That is, I want to detect all consecutive sequences of the same fValue
> that intersect with the dates I requested (for the given fName) and
> output the start-time and end-time of each sequence. Is there any way to
> do so without resorting to client-side programming?
>
> Thanks
This is one of those cases I would consider a cursor - it might perform
better than a self join.
-----------------------
Alex Kuznetsov
http://sqlserver-tips.blogspot.com/
http://sqlserver-puzzles.blogspot.com/ >> Stay informed about: Detecting value changes and grouping by them |
|
| Back to top |
|
 |  |
External

Since: Dec 21, 2006 Posts: 7
|
(Msg. 5) Posted: Thu Dec 21, 2006 11:03 pm
Post subject: Re: Detecting value changes and grouping by them [Login to view extended thread Info.] Archived from groups: per prev. post (more info?)
|
|
|
wrote:
> Using SQL Server 2005, you can do this (uses a difference of ranks)
>
> set nocount on
>
> create table tParams(fName char(4),fTime datetime,fValue int)
> insert into tParams(fName ,fTime ,fValue)
> select 'Par2' , '1/1/2006 00:00' , 9 union all
> select 'Par2' , '1/1/2006 00:01' , 9 union all
> select 'Par2' , '1/1/2006 00:02' , 5 union all
> select 'Par2' , '1/1/2006 00:03' , 5 union all
> select 'Par2' , '1/1/2006 00:04' , 5 union all
> select 'Par2' , '1/1/2006 00:05' , 3 union all
> select 'Par1' , '1/1/2006 00:00' , 1 union all
> select 'Par1' , '1/1/2006 00:01' , 1 union all
> select 'Par1' , '1/1/2006 00:02' , 1 union all
> select 'Par1' , '1/1/2006 00:03' , 1 union all
> select 'Par1' , '1/1/2006 00:04' , 2 union all
> select 'Par1' , '1/1/2006 00:05' , 2 union all
> select 'Par1' , '1/1/2006 00:06' , 2 union all
> select 'Par1' , '1/1/2006 00:07' , 2 union all
> select 'Par1' , '1/1/2006 00:08' , 3 union all
> select 'Par1' , '1/1/2006 00:09' , 3 union all
> select 'Par1' , '1/1/2006 00:10' , 1 union all
> select 'Par1' , '1/1/2006 00:11' , 2 union all
> select 'Par1' , '1/1/2006 00:12' , 2 union all
> select 'Par1' , '1/1/2006 00:13' , 4 union all
> select 'Par1' , '1/1/2006 00:14' , 4 union all
> select 'Par1' , '1/1/2006 00:15' , 4 ;
>
> with cte(fName,fTime,fValue,rn)
> as (select fName,
> fTime,
> fValue,
> rank() over(partition by fName order by fTime)-
> rank() over(partition by fName,fValue order by fTime)
> from tParams)
> select min(fTime) as FromTime,
> max(fTime) as ToTime,
> fValue as Lbl
> from cte
> where fName = 'Par1'
> group by fName,fValue,Rn
> having (min(fTime) <= '2006-1-1 00:14')
> and (max(fTime) >= '2006-1-1 00:05')
> order by FromTime
>
>
> Note that this is also possible with SQL Server 2000, but is a bit more
> complex
>
Thanks for the quick response but I'm afraid I'm using SQL Server 2000.
I need a method that works on both SQL Server 2000 and 2005, and is
relatively fast (the query should run on approx. 13,000 records matching
a single parameter fName in less than 5 seconds. The entire table
containing all the parameters is about 5,000,000 records long). >> Stay informed about: Detecting value changes and grouping by them |
|
| Back to top |
|
 |  |
External

Since: Dec 21, 2006 Posts: 7
|
(Msg. 6) Posted: Fri Dec 22, 2006 12:42 am
Post subject: Re: Detecting value changes and grouping by them [Login to view extended thread Info.] Archived from groups: per prev. post (more info?)
|
|
|
wrote:
> Here's a SQL Server 2000 version to try, not sure how well it will
> perform.
>
>
> select min(fTime) as FromTime,
> max(fTime) as ToTime,
> fValue as Lbl
> from (select t.fName,
> t.fTime,
> t.fValue,
> (select count(*)
> from tParams t2
> where t2.fName=t.fName
> and t2.fTime<=t.fTime)-
> (select count(*)
> from tParams t2
> where t2.fName=t.fName
> and t2.fValue=t.fValue
> and t2.fTime<=t.fTime)
> from tParams t
> where t.fName = 'Par1') as X(fName,fTime,fValue,rn)
> group by fName,fValue,Rn
> having (min(fTime) <= '2006-1-1 00:14')
> and (max(fTime) >= '2006-1-1 00:05')
> order by FromTime
>
I only let it loose on 17 hours worth of data (normal running size is
one week) and after 10 minutes I got the equivalent of a select query
without group by (I got all the records for "Par1" between the given times):
FromTime ToTime Lbl
-------- ------ ---
fTime fTime fValue
.. . .
.. . .
.. . .
For each of the original records in range.
I appreciate the effort though... >> Stay informed about: Detecting value changes and grouping by them |
|
| Back to top |
|
 |  |
External

Since: Jul 26, 2004 Posts: 18
|
(Msg. 7) Posted: Fri Dec 22, 2006 8:31 am
Post subject: Re: Detecting value changes and grouping by them [Login to view extended thread Info.] Archived from groups: per prev. post (more info?)
|
|
|
Zero One wrote:
> Thanks for the quick response but I'm afraid I'm using SQL Server 2000.
> I need a method that works on both SQL Server 2000 and 2005, and is
> relatively fast (the query should run on approx. 13,000 records matching
> a single parameter fName in less than 5 seconds. The entire table
> containing all the parameters is about 5,000,000 records long).
IMHO this should be fast enough:
select
fName, min(fTime), max(fTime), fValue
from
(
select
fName,
fTime,
fValue,
(select min(fTime)
from tParams t2
where t2.fName = t.fName
and t2.fTime > t.fTime
and t2.fValue <> t.fValue) as grp
from tParams as t
where t.fName = 'Par1'
) dt
group by fName, grp, fValue
having (min(fTime) <= '2006-1-1 00:14')
and (max(fTime) >= '2006-1-1 00:05')
order by 1,2;
Dieter >> Stay informed about: Detecting value changes and grouping by them |
|
| Back to top |
|
 |  |
External

Since: Aug 08, 2006 Posts: 17
|
(Msg. 8) Posted: Fri Dec 22, 2006 10:06 am
Post subject: Re: Detecting value changes and grouping by them [Login to view extended thread Info.] Archived from groups: per prev. post (more info?)
|
|
|
Yes, a cursor would perform best here. Don't be afraid of them...
"Alex Kuznetsov" wrote in message
>
> Zero One wrote:
>> Hello,
>>
>> I was wondering if anyone can help me with a problem I have. I have a
>> program (beyond my control) that constantly posts to a table the current
>> value of a set of parameters identified by name. I need to query it and
>> return for a given parameter and start\end times which values it had
>> between those times and the minimum and maximum times for each value.
>>
>> To clarify, suppose I have the following table:
>>
>> fName fTime fValue
>> ----- ----- ------
>> Par2 1/1/2006 00:00 9
>> Par2 1/1/2006 00:01 9
>> Par2 1/1/2006 00:02 5
>> Par2 1/1/2006 00:03 5
>> Par2 1/1/2006 00:04 5
>> Par2 1/1/2006 00:05 3
>> Par1 1/1/2006 00:00 1
>> Par1 1/1/2006 00:01 1
>> Par1 1/1/2006 00:02 1
>> Par1 1/1/2006 00:03 1
>> Par1 1/1/2006 00:04 2
>> Par1 1/1/2006 00:05 2
>> Par1 1/1/2006 00:06 2
>> Par1 1/1/2006 00:07 2
>> Par1 1/1/2006 00:08 3
>> Par1 1/1/2006 00:09 3
>> Par1 1/1/2006 00:10 1
>> Par1 1/1/2006 00:11 2
>> Par1 1/1/2006 00:12 2
>> Par1 1/1/2006 00:13 4
>> Par1 1/1/2006 00:14 4
>> Par1 1/1/2006 00:15 4
>>
>> For the parameter "Par1" and the time range "1/1/2006 00:05" to
>> "1/1/2006 00:14" I run the following query:
>>
>> SELECT Min(fTime) AS FromTime, Max(fTime) AS ToTime, fValue AS Lbl
>> FROM tParams
>> WHERE (fName = 'Par1')
>> GROUP BY fName, fValue
>> HAVING (Min(fTime) <= '2006-1-1 00:14')
>> AND (Max(fTime) >= '2006-1-1 00:05')
>>
>> And get the following result:
>>
>> FromTime ToTime Lbl
>> -------- ------ ---
>> 1/1/2006 00:04 1/1/2006 00:12 2
>> 1/1/2006 00:08 1/1/2006 00:09 3
>> 1/1/2006 00:00 1/1/2006 00:10 1
>> 1/1/2006 00:13 1/1/2006 00:15 4
>>
>> What I'm actually trying to get is:
>>
>> FromTime ToTime Lbl
>> -------- ------ ---
>> 1/1/2006 00:04 1/1/2006 00:07 2
>> 1/1/2006 00:08 1/1/2006 00:09 3
>> 1/1/2006 00:10 1/1/2006 00:10 1
>> 1/1/2006 00:11 1/1/2006 00:12 2
>> 1/1/2006 00:13 1/1/2006 00:15 4
>>
>> That is, I want to detect all consecutive sequences of the same fValue
>> that intersect with the dates I requested (for the given fName) and
>> output the start-time and end-time of each sequence. Is there any way to
>> do so without resorting to client-side programming?
>>
>> Thanks
>
> This is one of those cases I would consider a cursor - it might perform
> better than a self join.
>
> -----------------------
> Alex Kuznetsov
> http://sqlserver-tips.blogspot.com/
> http://sqlserver-puzzles.blogspot.com/
> >> Stay informed about: Detecting value changes and grouping by them |
|
| Back to top |
|
 |  |
External

Since: Dec 21, 2006 Posts: 7
|
(Msg. 9) Posted: Sun Dec 24, 2006 3:49 pm
Post subject: Re: Detecting value changes and grouping by them [Login to view extended thread Info.] Archived from groups: per prev. post (more info?)
|
|
|
Dieter Noeth wrote:
> Zero One wrote:
>
>> Thanks for the quick response but I'm afraid I'm using SQL Server 2000.
>> I need a method that works on both SQL Server 2000 and 2005, and is
>> relatively fast (the query should run on approx. 13,000 records
>> matching a single parameter fName in less than 5 seconds. The entire
>> table containing all the parameters is about 5,000,000 records long).
>
> IMHO this should be fast enough:
>
> select
> fName, min(fTime), max(fTime), fValue
> from
> (
> select
> fName,
> fTime,
> fValue,
> (select min(fTime)
> from tParams t2
> where t2.fName = t.fName
> and t2.fTime > t.fTime
> and t2.fValue <> t.fValue) as grp
> from tParams as t
> where t.fName = 'Par1'
> ) dt
> group by fName, grp, fValue
> having (min(fTime) <= '2006-1-1 00:14')
> and (max(fTime) >= '2006-1-1 00:05')
> order by 1,2;
>
> Dieter
On 17 hours worth of data (normal running size is one week) this query
took ~1 minute to execute which makes it too slow for what I need. On
the bright side, it does seem to work perfectly
Thanks
p.s.
Sorry I didn't reply earlier - I forgot to press the "send" button on my
reader... >> Stay informed about: Detecting value changes and grouping by them |
|
| Back to top |
|
 |  |
| Related Topics: | Detecting an existence of local temporary table - Hi, I create a temporary table. for example: <font color=purple> ; create table #t1 (ID_T1 integer)</font> Next I would like to detect If the table already exists: exec sp_table #t1 if @@ROWCOUNT > 0 <font color=purple>&...
Grouping Question - I've not needed to use grouping before so Im looking for guidence. My View ---------- Project_no ProjectName Week_no RawCost XXXXX1 ARK 2 20 XXXXX1 ARK 3 20 XXXXX1 ...
Troubles with grouping - Hi all, I have an SQL query (which I'm going to dumb down here) which I am trying to output. Say I currently have an output of REQNUMBER USERCODE --------------------- ------------------------ 1123 SMIT...
Help with grouping and selection - I have a record set of 25,000 records ( which is growing ). For the sake of the example, the view looks like this. pyear( int ) week_no( int ) marketSpace( string ) project_no( string ) cost( double) I want to group by market space , project_no and..
HELP with Grouping View - Hi All, I am new to this group and semi-new to SQL views. I am experienced with Access queries and always compare the two. I created a view that would be what Access refers to as a crosstab query. I have accomplished the task but would like to furthe... |
|
You can post new topics in this forum You can reply to topics in this forum You can edit your posts in this forum You can delete your posts in this forum You can vote in polls in this forum
|
|
|
|
 |
|
|