Como elimino el cursor

03/05/2006 - 21:27 por Horacio | Informe spam
Hola,

Primero les comento cual es la necesidad y como la resolvimos:

Tenemos que guardar los datos provenientes de distintas fuentes, estos datos
estan compuesto por clave (codTag), valor, fechaHora (momento en que se
genero el dato, no momento de insercion), y un valor de alarma que no nos
interesa.

La tabla tiene esta estructura:

CREATE TABLE [dbo].[ValoresHistoricos] (
[codTag] [smallint] NOT NULL ,
[valor] [float] NULL ,
[fechaHora] [datetime] NOT NULL ,
[alarma] [varchar] (6) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]

Se permite null en el campo valor porque tiene un significado especial para
la aplicacion.

El tema es que ahora necesitamos calcular datos como un promedio ponderado
en el tiempo. Por ej (olvidandonos del campo alarma):

codTag Valor FechaHora
1, 400, '1/1/1 00:00:00'
1, 200, '1/1/1 00:10:00'
1, 150, '1/1/1 00:30:00'
1, 100, '1/1/1 01:10:00'

el promedio ponderado en el tiempo para el codTag = 1 es:
400 * 10 minutos (son 10 minutos porque ese es el tiempo que duro en ese
valor)
+
200 * 20
+
150*40
000
Todo dividido 70 minutos
0 (este es el promedio ponderado en el tiempo para este codTag en ese
periodo)
La pregunta es:
¿Se puede obtener este resultado sin recurrir a un cursor como actualmente
se hace?

¿Es necesario proponer otra estructura en la tabla para mejorar el
rendimiento y evitar el cursor?

Hemos intentado hacer algo diferente precalculando valores mediante
triggers, pero se complica porque los datos pueden llegar a entrar
desordenados cronologicamente. Ejemplo, hoy pueden estar entrendo datos
actuales y datos de ayer para el mismo codTag.

Cualquier otra informacion que necesiten no duden en solicitarla.

Muchas gracias por su tiempo.

Saludos

Horacio

Preguntas similare

Leer las respuestas

#1 Alejandro Mesa
03/05/2006 - 21:43 | Informe spam
Trata,

select
a.codTag, sum(a.valor * datediff(minute, a.fechaHora, b.fechaHora)) /
datediff(minute, min(a.fechaHora), max(b.fechaHora))
from
[dbo].[ValoresHistoricos] as a
inner join
[dbo].[ValoresHistoricos] as b
on b.codTag = a.codTag
and b.fechaHora = (select min(c.fechaHora) from [dbo].[ValoresHistoricos]
as c where b.codTag = a.codTag and c.fechaHora > a.fechaHora)
group by
a.codTag
go


AMB

"Horacio" wrote:

Hola,

Primero les comento cual es la necesidad y como la resolvimos:

Tenemos que guardar los datos provenientes de distintas fuentes, estos datos
estan compuesto por clave (codTag), valor, fechaHora (momento en que se
genero el dato, no momento de insercion), y un valor de alarma que no nos
interesa.

La tabla tiene esta estructura:

CREATE TABLE [dbo].[ValoresHistoricos] (
[codTag] [smallint] NOT NULL ,
[valor] [float] NULL ,
[fechaHora] [datetime] NOT NULL ,
[alarma] [varchar] (6) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]

Se permite null en el campo valor porque tiene un significado especial para
la aplicacion.

El tema es que ahora necesitamos calcular datos como un promedio ponderado
en el tiempo. Por ej (olvidandonos del campo alarma):

codTag Valor FechaHora
1, 400, '1/1/1 00:00:00'
1, 200, '1/1/1 00:10:00'
1, 150, '1/1/1 00:30:00'
1, 100, '1/1/1 01:10:00'

el promedio ponderado en el tiempo para el codTag = 1 es:
400 * 10 minutos (son 10 minutos porque ese es el tiempo que duro en ese
valor)
+
200 * 20
+
150*40
000
Todo dividido 70 minutos
0 (este es el promedio ponderado en el tiempo para este codTag en ese
periodo)
La pregunta es:
¿Se puede obtener este resultado sin recurrir a un cursor como actualmente
se hace?

¿Es necesario proponer otra estructura en la tabla para mejorar el
rendimiento y evitar el cursor?

Hemos intentado hacer algo diferente precalculando valores mediante
triggers, pero se complica porque los datos pueden llegar a entrar
desordenados cronologicamente. Ejemplo, hoy pueden estar entrendo datos
actuales y datos de ayer para el mismo codTag.

Cualquier otra informacion que necesiten no duden en solicitarla.

Muchas gracias por su tiempo.

Saludos

Horacio


Respuesta Responder a este mensaje
#2 Horacio
03/05/2006 - 22:17 | Informe spam
Gracias por tu respuesta Alejandro!

Con este pack de datos deveria dar 266,66, pero obtengo 320 con tu solución.

insert into valoreshistoricos values (11111,350, '20060503 00:00','HRC')
insert into valoreshistoricos values (11111,150, '20060503 00:10','HRC')
insert into valoreshistoricos values (11111,400, '20060503 00:40','HRC')
insert into valoreshistoricos values (11111,200, '20060503 01:10','HRC')
insert into valoreshistoricos values (11111,250, '20060503 01:30','HRC')

Conste que yo le agrege:

having a.codtag111

al final de la consulta.

De todas formas, si la solución viene por este lado, que indices me
recomendas modificar para obtener un mejor rendimiento.

Saludos

Horacio


"Alejandro Mesa" escribió:

Trata,

select
a.codTag, sum(a.valor * datediff(minute, a.fechaHora, b.fechaHora)) /
datediff(minute, min(a.fechaHora), max(b.fechaHora))
from
[dbo].[ValoresHistoricos] as a
inner join
[dbo].[ValoresHistoricos] as b
on b.codTag = a.codTag
and b.fechaHora = (select min(c.fechaHora) from [dbo].[ValoresHistoricos]
as c where b.codTag = a.codTag and c.fechaHora > a.fechaHora)
group by
a.codTag
go


AMB

"Horacio" wrote:

> Hola,
>
> Primero les comento cual es la necesidad y como la resolvimos:
>
> Tenemos que guardar los datos provenientes de distintas fuentes, estos datos
> estan compuesto por clave (codTag), valor, fechaHora (momento en que se
> genero el dato, no momento de insercion), y un valor de alarma que no nos
> interesa.
>
> La tabla tiene esta estructura:
>
> CREATE TABLE [dbo].[ValoresHistoricos] (
> [codTag] [smallint] NOT NULL ,
> [valor] [float] NULL ,
> [fechaHora] [datetime] NOT NULL ,
> [alarma] [varchar] (6) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
> ) ON [PRIMARY]
>
> Se permite null en el campo valor porque tiene un significado especial para
> la aplicacion.
>
> El tema es que ahora necesitamos calcular datos como un promedio ponderado
> en el tiempo. Por ej (olvidandonos del campo alarma):
>
> codTag Valor FechaHora
> 1, 400, '1/1/1 00:00:00'
> 1, 200, '1/1/1 00:10:00'
> 1, 150, '1/1/1 00:30:00'
> 1, 100, '1/1/1 01:10:00'
>
> el promedio ponderado en el tiempo para el codTag = 1 es:
> 400 * 10 minutos (son 10 minutos porque ese es el tiempo que duro en ese
> valor)
> +
> 200 * 20
> +
> 150*40
> 000
> Todo dividido 70 minutos
> 0 (este es el promedio ponderado en el tiempo para este codTag en ese
> periodo)
> La pregunta es:
> ¿Se puede obtener este resultado sin recurrir a un cursor como actualmente
> se hace?
>
> ¿Es necesario proponer otra estructura en la tabla para mejorar el
> rendimiento y evitar el cursor?
>
> Hemos intentado hacer algo diferente precalculando valores mediante
> triggers, pero se complica porque los datos pueden llegar a entrar
> desordenados cronologicamente. Ejemplo, hoy pueden estar entrendo datos
> actuales y datos de ayer para el mismo codTag.
>
> Cualquier otra informacion que necesiten no duden en solicitarla.
>
> Muchas gracias por su tiempo.
>
> Saludos
>
> Horacio
>
>
Respuesta Responder a este mensaje
#3 Alejandro Mesa
03/05/2006 - 22:35 | Informe spam
Horacio,

Estas seguro que la alarma no es importante en este calculo?. Chequea a ver
cuantas filas existen en tu tabla donde codTag = 11111. Cuando ejecuto la
sentencia en mi maquina solo con el grupo que me distes, este es el resultado:

codTag
11111 266.66666666666669

(1 row(s) affected)


En cuanto a los indices, no tengo informacion suficiente como para decirte
cuales si y cuales no, pero pudieras empezar por decirnos cual es la clave
primaria de esa tabla. Pudieras empezar con:

create clustered index ValoresHistoricos_fechaHora_nu_c_idx
on [dbo].[ValoresHistoricos] (fechaHora)
go

create nonclustered index ValoresHistoricos_codTag_nu_nc_idx
on [dbo].[ValoresHistoricos] (codTag)
go


AMB

"Horacio" wrote:

Gracias por tu respuesta Alejandro!

Con este pack de datos deveria dar 266,66, pero obtengo 320 con tu solución.

insert into valoreshistoricos values (11111,350, '20060503 00:00','HRC')
insert into valoreshistoricos values (11111,150, '20060503 00:10','HRC')
insert into valoreshistoricos values (11111,400, '20060503 00:40','HRC')
insert into valoreshistoricos values (11111,200, '20060503 01:10','HRC')
insert into valoreshistoricos values (11111,250, '20060503 01:30','HRC')

Conste que yo le agrege:

having a.codtag111

al final de la consulta.

De todas formas, si la solución viene por este lado, que indices me
recomendas modificar para obtener un mejor rendimiento.

Saludos

Horacio


"Alejandro Mesa" escribió:

> Trata,
>
> select
> a.codTag, sum(a.valor * datediff(minute, a.fechaHora, b.fechaHora)) /
> datediff(minute, min(a.fechaHora), max(b.fechaHora))
> from
> [dbo].[ValoresHistoricos] as a
> inner join
> [dbo].[ValoresHistoricos] as b
> on b.codTag = a.codTag
> and b.fechaHora = (select min(c.fechaHora) from [dbo].[ValoresHistoricos]
> as c where b.codTag = a.codTag and c.fechaHora > a.fechaHora)
> group by
> a.codTag
> go
>
>
> AMB
>
> "Horacio" wrote:
>
> > Hola,
> >
> > Primero les comento cual es la necesidad y como la resolvimos:
> >
> > Tenemos que guardar los datos provenientes de distintas fuentes, estos datos
> > estan compuesto por clave (codTag), valor, fechaHora (momento en que se
> > genero el dato, no momento de insercion), y un valor de alarma que no nos
> > interesa.
> >
> > La tabla tiene esta estructura:
> >
> > CREATE TABLE [dbo].[ValoresHistoricos] (
> > [codTag] [smallint] NOT NULL ,
> > [valor] [float] NULL ,
> > [fechaHora] [datetime] NOT NULL ,
> > [alarma] [varchar] (6) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
> > ) ON [PRIMARY]
> >
> > Se permite null en el campo valor porque tiene un significado especial para
> > la aplicacion.
> >
> > El tema es que ahora necesitamos calcular datos como un promedio ponderado
> > en el tiempo. Por ej (olvidandonos del campo alarma):
> >
> > codTag Valor FechaHora
> > 1, 400, '1/1/1 00:00:00'
> > 1, 200, '1/1/1 00:10:00'
> > 1, 150, '1/1/1 00:30:00'
> > 1, 100, '1/1/1 01:10:00'
> >
> > el promedio ponderado en el tiempo para el codTag = 1 es:
> > 400 * 10 minutos (son 10 minutos porque ese es el tiempo que duro en ese
> > valor)
> > +
> > 200 * 20
> > +
> > 150*40
> > 000
> > Todo dividido 70 minutos
> > 0 (este es el promedio ponderado en el tiempo para este codTag en ese
> > periodo)
> > La pregunta es:
> > ¿Se puede obtener este resultado sin recurrir a un cursor como actualmente
> > se hace?
> >
> > ¿Es necesario proponer otra estructura en la tabla para mejorar el
> > rendimiento y evitar el cursor?
> >
> > Hemos intentado hacer algo diferente precalculando valores mediante
> > triggers, pero se complica porque los datos pueden llegar a entrar
> > desordenados cronologicamente. Ejemplo, hoy pueden estar entrendo datos
> > actuales y datos de ayer para el mismo codTag.
> >
> > Cualquier otra informacion que necesiten no duden en solicitarla.
> >
> > Muchas gracias por su tiempo.
> >
> > Saludos
> >
> > Horacio
> >
> >
Respuesta Responder a este mensaje
#4 Horacio
04/05/2006 - 15:09 | Informe spam
Que curioso...

El codTag 11111 lo genere para esta prueba. Y la alarma definitivamente no
influye.

Si creo una tabla nueva con solo esos datos, sí funciona, pero en cuanto
agrego datos deja comienza a fallar.

Te paso este nuevo pack de datos, el resultado debe ser el mismo para cada
codtag

insert into ValoresHistoricos2 values(11111,350,'May 3 2006 12:00AM ','NADA')
insert into ValoresHistoricos2 values(11111,150,'May 3 2006 12:10AM ','NADA')
insert into ValoresHistoricos2 values(11111,400,'May 3 2006 12:40AM ','NADA')
insert into ValoresHistoricos2 values(11111,200,'May 3 2006 1:10AM ','NADA')
insert into ValoresHistoricos2 values(11111,250,'May 3 2006 1:30AM ','NADA')
insert into ValoresHistoricos2 values(11112,350,'May 3 2006 12:10AM ','NADA')
insert into ValoresHistoricos2 values(11112,150,'May 3 2006 12:20AM ','NADA')
insert into ValoresHistoricos2 values(11112,400,'May 3 2006 12:50AM ','NADA')
insert into ValoresHistoricos2 values(11112,200,'May 3 2006 1:20AM ','NADA')
insert into ValoresHistoricos2 values(11112,250,'May 3 2006 1:40AM ','NADA')
insert into ValoresHistoricos2 values(11113,350,'May 3 2006 12:20AM ','NADA')
insert into ValoresHistoricos2 values(11113,150,'May 3 2006 12:30AM ','NADA')
insert into ValoresHistoricos2 values(11114,400,'May 3 2006 1:10AM ','NADA')
insert into ValoresHistoricos2 values(11114,200,'May 3 2006 1:40AM ','NADA')
insert into ValoresHistoricos2 values(11114,250,'May 3 2006 2:00AM ','NADA')
insert into ValoresHistoricos2 values(11114,350,'May 3 2006 12:30AM ','NADA')
insert into ValoresHistoricos2 values(11114,150,'May 3 2006 12:40AM ','NADA')
insert into ValoresHistoricos2 values(11113,400,'May 3 2006 1:00AM ','NADA')
insert into ValoresHistoricos2 values(11113,200,'May 3 2006 1:30AM ','NADA')
insert into ValoresHistoricos2 values(11113,250,'May 3 2006 1:50AM ','NADA')

Muchas gracias

"Alejandro Mesa" wrote:

Horacio,

Estas seguro que la alarma no es importante en este calculo?. Chequea a ver
cuantas filas existen en tu tabla donde codTag = 11111. Cuando ejecuto la
sentencia en mi maquina solo con el grupo que me distes, este es el resultado:

codTag
11111 266.66666666666669

(1 row(s) affected)


En cuanto a los indices, no tengo informacion suficiente como para decirte
cuales si y cuales no, pero pudieras empezar por decirnos cual es la clave
primaria de esa tabla. Pudieras empezar con:

create clustered index ValoresHistoricos_fechaHora_nu_c_idx
on [dbo].[ValoresHistoricos] (fechaHora)
go

create nonclustered index ValoresHistoricos_codTag_nu_nc_idx
on [dbo].[ValoresHistoricos] (codTag)
go


AMB

"Horacio" wrote:

> Gracias por tu respuesta Alejandro!
>
> Con este pack de datos deveria dar 266,66, pero obtengo 320 con tu solución.
>
> insert into valoreshistoricos values (11111,350, '20060503 00:00','HRC')
> insert into valoreshistoricos values (11111,150, '20060503 00:10','HRC')
> insert into valoreshistoricos values (11111,400, '20060503 00:40','HRC')
> insert into valoreshistoricos values (11111,200, '20060503 01:10','HRC')
> insert into valoreshistoricos values (11111,250, '20060503 01:30','HRC')
>
> Conste que yo le agrege:
>
> having a.codtag111
>
> al final de la consulta.
>
> De todas formas, si la solución viene por este lado, que indices me
> recomendas modificar para obtener un mejor rendimiento.
>
> Saludos
>
> Horacio
>
>
> "Alejandro Mesa" escribió:
>
> > Trata,
> >
> > select
> > a.codTag, sum(a.valor * datediff(minute, a.fechaHora, b.fechaHora)) /
> > datediff(minute, min(a.fechaHora), max(b.fechaHora))
> > from
> > [dbo].[ValoresHistoricos] as a
> > inner join
> > [dbo].[ValoresHistoricos] as b
> > on b.codTag = a.codTag
> > and b.fechaHora = (select min(c.fechaHora) from [dbo].[ValoresHistoricos]
> > as c where b.codTag = a.codTag and c.fechaHora > a.fechaHora)
> > group by
> > a.codTag
> > go
> >
> >
> > AMB
> >
> > "Horacio" wrote:
> >
> > > Hola,
> > >
> > > Primero les comento cual es la necesidad y como la resolvimos:
> > >
> > > Tenemos que guardar los datos provenientes de distintas fuentes, estos datos
> > > estan compuesto por clave (codTag), valor, fechaHora (momento en que se
> > > genero el dato, no momento de insercion), y un valor de alarma que no nos
> > > interesa.
> > >
> > > La tabla tiene esta estructura:
> > >
> > > CREATE TABLE [dbo].[ValoresHistoricos] (
> > > [codTag] [smallint] NOT NULL ,
> > > [valor] [float] NULL ,
> > > [fechaHora] [datetime] NOT NULL ,
> > > [alarma] [varchar] (6) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
> > > ) ON [PRIMARY]
> > >
> > > Se permite null en el campo valor porque tiene un significado especial para
> > > la aplicacion.
> > >
> > > El tema es que ahora necesitamos calcular datos como un promedio ponderado
> > > en el tiempo. Por ej (olvidandonos del campo alarma):
> > >
> > > codTag Valor FechaHora
> > > 1, 400, '1/1/1 00:00:00'
> > > 1, 200, '1/1/1 00:10:00'
> > > 1, 150, '1/1/1 00:30:00'
> > > 1, 100, '1/1/1 01:10:00'
> > >
> > > el promedio ponderado en el tiempo para el codTag = 1 es:
> > > 400 * 10 minutos (son 10 minutos porque ese es el tiempo que duro en ese
> > > valor)
> > > +
> > > 200 * 20
> > > +
> > > 150*40
> > > 000
> > > Todo dividido 70 minutos
> > > 0 (este es el promedio ponderado en el tiempo para este codTag en ese
> > > periodo)
> > > La pregunta es:
> > > ¿Se puede obtener este resultado sin recurrir a un cursor como actualmente
> > > se hace?
> > >
> > > ¿Es necesario proponer otra estructura en la tabla para mejorar el
> > > rendimiento y evitar el cursor?
> > >
> > > Hemos intentado hacer algo diferente precalculando valores mediante
> > > triggers, pero se complica porque los datos pueden llegar a entrar
> > > desordenados cronologicamente. Ejemplo, hoy pueden estar entrendo datos
> > > actuales y datos de ayer para el mismo codTag.
> > >
> > > Cualquier otra informacion que necesiten no duden en solicitarla.
> > >
> > > Muchas gracias por su tiempo.
> > >
> > > Saludos
> > >
> > > Horacio
> > >
> > >
Respuesta Responder a este mensaje
#5 Horacio
04/05/2006 - 15:18 | Informe spam
Ahora si.

Agregue
and a.codtag=c.codtag
En:
(select min(c.fechaHora) from [dbo].[ValoresHistoricos2]
as c where b.codTag = a.codTag and c.fechaHora > a.fechaHora)

Y ahora funciona.

Me puedo quedar tranquilo con esta solución? Se te ocurre alguna otra prueba
para verificar el resultado?

Te soy sincero, lo puse ahi porque me parecio logico, pero no estoy seguro
de comprender como funciona la consulta. Y está claro que nunca hubiera
llegado a esa solución.

Muchas gracias


"Horacio" wrote:

Que curioso...

El codTag 11111 lo genere para esta prueba. Y la alarma definitivamente no
influye.

Si creo una tabla nueva con solo esos datos, sí funciona, pero en cuanto
agrego datos deja comienza a fallar.

Te paso este nuevo pack de datos, el resultado debe ser el mismo para cada
codtag

insert into ValoresHistoricos2 values(11111,350,'May 3 2006 12:00AM ','NADA')
insert into ValoresHistoricos2 values(11111,150,'May 3 2006 12:10AM ','NADA')
insert into ValoresHistoricos2 values(11111,400,'May 3 2006 12:40AM ','NADA')
insert into ValoresHistoricos2 values(11111,200,'May 3 2006 1:10AM ','NADA')
insert into ValoresHistoricos2 values(11111,250,'May 3 2006 1:30AM ','NADA')
insert into ValoresHistoricos2 values(11112,350,'May 3 2006 12:10AM ','NADA')
insert into ValoresHistoricos2 values(11112,150,'May 3 2006 12:20AM ','NADA')
insert into ValoresHistoricos2 values(11112,400,'May 3 2006 12:50AM ','NADA')
insert into ValoresHistoricos2 values(11112,200,'May 3 2006 1:20AM ','NADA')
insert into ValoresHistoricos2 values(11112,250,'May 3 2006 1:40AM ','NADA')
insert into ValoresHistoricos2 values(11113,350,'May 3 2006 12:20AM ','NADA')
insert into ValoresHistoricos2 values(11113,150,'May 3 2006 12:30AM ','NADA')
insert into ValoresHistoricos2 values(11114,400,'May 3 2006 1:10AM ','NADA')
insert into ValoresHistoricos2 values(11114,200,'May 3 2006 1:40AM ','NADA')
insert into ValoresHistoricos2 values(11114,250,'May 3 2006 2:00AM ','NADA')
insert into ValoresHistoricos2 values(11114,350,'May 3 2006 12:30AM ','NADA')
insert into ValoresHistoricos2 values(11114,150,'May 3 2006 12:40AM ','NADA')
insert into ValoresHistoricos2 values(11113,400,'May 3 2006 1:00AM ','NADA')
insert into ValoresHistoricos2 values(11113,200,'May 3 2006 1:30AM ','NADA')
insert into ValoresHistoricos2 values(11113,250,'May 3 2006 1:50AM ','NADA')

Muchas gracias

"Alejandro Mesa" wrote:

> Horacio,
>
> Estas seguro que la alarma no es importante en este calculo?. Chequea a ver
> cuantas filas existen en tu tabla donde codTag = 11111. Cuando ejecuto la
> sentencia en mi maquina solo con el grupo que me distes, este es el resultado:
>
> codTag
> 11111 266.66666666666669
>
> (1 row(s) affected)
>
>
> En cuanto a los indices, no tengo informacion suficiente como para decirte
> cuales si y cuales no, pero pudieras empezar por decirnos cual es la clave
> primaria de esa tabla. Pudieras empezar con:
>
> create clustered index ValoresHistoricos_fechaHora_nu_c_idx
> on [dbo].[ValoresHistoricos] (fechaHora)
> go
>
> create nonclustered index ValoresHistoricos_codTag_nu_nc_idx
> on [dbo].[ValoresHistoricos] (codTag)
> go
>
>
> AMB
>
> "Horacio" wrote:
>
> > Gracias por tu respuesta Alejandro!
> >
> > Con este pack de datos deveria dar 266,66, pero obtengo 320 con tu solución.
> >
> > insert into valoreshistoricos values (11111,350, '20060503 00:00','HRC')
> > insert into valoreshistoricos values (11111,150, '20060503 00:10','HRC')
> > insert into valoreshistoricos values (11111,400, '20060503 00:40','HRC')
> > insert into valoreshistoricos values (11111,200, '20060503 01:10','HRC')
> > insert into valoreshistoricos values (11111,250, '20060503 01:30','HRC')
> >
> > Conste que yo le agrege:
> >
> > having a.codtag111
> >
> > al final de la consulta.
> >
> > De todas formas, si la solución viene por este lado, que indices me
> > recomendas modificar para obtener un mejor rendimiento.
> >
> > Saludos
> >
> > Horacio
> >
> >
> > "Alejandro Mesa" escribió:
> >
> > > Trata,
> > >
> > > select
> > > a.codTag, sum(a.valor * datediff(minute, a.fechaHora, b.fechaHora)) /
> > > datediff(minute, min(a.fechaHora), max(b.fechaHora))
> > > from
> > > [dbo].[ValoresHistoricos] as a
> > > inner join
> > > [dbo].[ValoresHistoricos] as b
> > > on b.codTag = a.codTag
> > > and b.fechaHora = (select min(c.fechaHora) from [dbo].[ValoresHistoricos]
> > > as c where b.codTag = a.codTag and c.fechaHora > a.fechaHora)
> > > group by
> > > a.codTag
> > > go
> > >
> > >
> > > AMB
> > >
> > > "Horacio" wrote:
> > >
> > > > Hola,
> > > >
> > > > Primero les comento cual es la necesidad y como la resolvimos:
> > > >
> > > > Tenemos que guardar los datos provenientes de distintas fuentes, estos datos
> > > > estan compuesto por clave (codTag), valor, fechaHora (momento en que se
> > > > genero el dato, no momento de insercion), y un valor de alarma que no nos
> > > > interesa.
> > > >
> > > > La tabla tiene esta estructura:
> > > >
> > > > CREATE TABLE [dbo].[ValoresHistoricos] (
> > > > [codTag] [smallint] NOT NULL ,
> > > > [valor] [float] NULL ,
> > > > [fechaHora] [datetime] NOT NULL ,
> > > > [alarma] [varchar] (6) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
> > > > ) ON [PRIMARY]
> > > >
> > > > Se permite null en el campo valor porque tiene un significado especial para
> > > > la aplicacion.
> > > >
> > > > El tema es que ahora necesitamos calcular datos como un promedio ponderado
> > > > en el tiempo. Por ej (olvidandonos del campo alarma):
> > > >
> > > > codTag Valor FechaHora
> > > > 1, 400, '1/1/1 00:00:00'
> > > > 1, 200, '1/1/1 00:10:00'
> > > > 1, 150, '1/1/1 00:30:00'
> > > > 1, 100, '1/1/1 01:10:00'
> > > >
> > > > el promedio ponderado en el tiempo para el codTag = 1 es:
> > > > 400 * 10 minutos (son 10 minutos porque ese es el tiempo que duro en ese
> > > > valor)
> > > > +
> > > > 200 * 20
> > > > +
> > > > 150*40
> > > > 000
> > > > Todo dividido 70 minutos
> > > > 0 (este es el promedio ponderado en el tiempo para este codTag en ese
> > > > periodo)
> > > > La pregunta es:
> > > > ¿Se puede obtener este resultado sin recurrir a un cursor como actualmente
> > > > se hace?
> > > >
> > > > ¿Es necesario proponer otra estructura en la tabla para mejorar el
> > > > rendimiento y evitar el cursor?
> > > >
> > > > Hemos intentado hacer algo diferente precalculando valores mediante
> > > > triggers, pero se complica porque los datos pueden llegar a entrar
> > > > desordenados cronologicamente. Ejemplo, hoy pueden estar entrendo datos
> > > > actuales y datos de ayer para el mismo codTag.
> > > >
> > > > Cualquier otra informacion que necesiten no duden en solicitarla.
> > > >
> > > > Muchas gracias por su tiempo.
> > > >
> > > > Saludos
> > > >
> > > > Horacio
> > > >
> > > >
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida