Necesito ayuda con esto por favor

26/08/2004 - 18:25 por Julio | Informe spam
Hola grupo

Tengo un problema con algo aqui y quisiera ver si me pueden dar una mano con
esto.

Tengo una tabla llamada Consumo la cual es alimentada por un DTS que
introduce todos los datos en ellas, tengo un caso y es el siguiente.
Cada vez que se haga un insert en la tabla consumo el campo que dice
Potencia de la tabla Consumo sera igual al average de las dos potencia mas
alta en el caso que esta sean mayor que la potencia que se inserto, en caso
de ser menor se queda la
potencia que se inserto.

entonces en la tabla consumo se hace todo el insert sin hacer ninguna
comparacion es decir el campo potencia se inserta tal como viene, luego creo
una vista llamada ConsumoAP para hacer los calculos.

Para que se pueda entende mejor este proyecto es para facturar la energia
electrica consumida por un usuario,como ya saben todos los meses se le cobra
lo que consumieron y si la potencia que consumieron es mayor que las dos mas
alta entonces se le cobra esa, de lo contario se
le cobraria el average.

En la vista ConsumoAP quiero sustituir el select que dice Select
Max(Potencia) por el valor de de lo explicado anteriormente.

Esta son las tablas:

Tabla de consumo :

CREATE TABLE [dbo].[Consumo] (
[ConsumoID] [int] IDENTITY (1, 1) NOT NULL ,
[ClienteID] [int] NOT NULL ,
[Fecha] [datetime] NOT NULL ,
[Energia] [decimal](18, 2) NULL ,
[Reactiva] [decimal](18, 2) NULL ,
[Potencia] [decimal](18, 2) NULL ,
[Potencia_punta] [decimal](18, 2) NULL ,
[Mes] AS (case (datepart(month,[fecha])) when '01' then 'Enero' when '02'
then 'Febrero' when '03' then 'Marzo' when '04' then 'Abril' when '05' then
'Mayo' when '06' then 'Junio' when '07' then 'Julio' when '08' then 'Agosto'
when '09' then 'Septiembre' when '10' then 'Octubre' when '11' then
'Noviembre' when '12' then 'Diciembre' end) ,
[Año] AS (datename(year,[fecha])) ,
[FechaInsertacion] [datetime] NULL ,
[Usuario] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]

Esta es la vista :

CREATE VIEW ConsumoAP
AS
SELECT Consumo.ConsumoID
, Consumo.Fecha
, Consumo.ClienteID
, Consumo.Mes
, Consumo.Año
, Consumo.Reactiva
, Consumo.Energia
, MAX(C2.Fecha) AS FechaConsumoAnterior

, (Select max(Potencia) From Consumo C2 Where C2.Clienteid Consumo.ClienteId)[Max_Potencia]

, (Select max(Potencia_Punta) From Consumo C2 Where C2.Clienteid Consumo.ClienteId)[Max_PotenciaPunta]
FROM Consumo
LEFT JOIN Consumo AS C2
ON Consumo.ClienteIdÂ.ClienteID
AND Consumo.Fecha>C2.Fecha
GROUP BY Consumo.ConsumoID
, Consumo.Fecha
, Consumo.ClienteID
, Consumo.Mes
, Consumo.Año
, Consumo.Reactiva
, Consumo.Energia



ejemplo


Tabla Consumo

Consumoid ClienteID Fecha Potencia
1 1 01/01/04 5
2 1 01/02/04 10
3 1 01/03/04 6
4 1 01/04/04 7



Vista quedaria asi

Consumoid ClienteID Fecha Potencia
1 1 01/01/04 5
2 1 01/02/04 10
3 1 01/03/04 7.5
4 1 01/04/04 8


Si observa para la fecha 01/04/04 en la tabla consumo la potencia fue igual
a 7, pero la vista tiene 8 ya que el promedio de las dos potencias mas alta
de la tabla consumo fueron igual 8 que es mayor que 7. Lo mismo sucede en la
fecha 01/03/04

Preguntas similare

Leer las respuestas

#11 Liliana Sorrentino
30/08/2004 - 13:24 | Informe spam
Julio, me parece que el código es lo suficientemente claro como para que
puedas modificarlo solo, pero por si no pudiste hacerlo, ahí va el cambio,
es en la vista, en el JOIN, la condición que compara la fecha de las
lecturas anteriores con la fecha actual menos 1 año.

CREATE VIEW Lecturas2PotenciasMayoresAnteriores(
ClienteID, FechaLectura, Potencia
, PotenciaAnterior1, PotenciaAnterior2)
AS
SELECT t1.clienteid, t1.fecha, t1.potencia, ISNULL(MAX(t2.potencia),0),
ISNULL(MAX(t3.potencia),0)
FROM consumo t1
LEFT JOIN CONSUMO t2 ON t1.clienteid = t2.clienteid AND t1.fecha > t2.fecha
AND t2.fecha >= datediff(yy, -1, t1.fecha)
LEFT JOIN CONSUMO t3 ON t1.clienteid = t3.clienteid AND t1.fecha > t3.fecha
AND t3.fecha >= datediff(yy, -1, t1.fecha) AND t2.potencia > t3.potencia
GROUP BY t1.clienteid, t1.fecha, t1.potencia
GO

SELECT ClienteID
, FechaLectura = convert(char(12), fechalectura)
, Potencia
, PotenciaAnterior1
, PotenciaAnterior2
, CASE WHEN PotenciaAnterior1 = 0 OR PotenciaAnterior2 = 0 THEN Potencia
WHEN (PotenciaAnterior2 + PotenciaAnterior1) / 2 < Potencia THEN
Potencia
ELSE CONVERT(DEC(10,2), (PotenciaAnterior2 + PotenciaAnterior1) / 2)
END AS PotenciaPunta
FROM Lecturas2PotenciasMayoresAnteriores

Liliana.
"Julio" escribió en el mensaje
news:
Hola Javier, Estuve probando el codigo pero solo me devuelve esto para un
solo cliente.
El codigo que me envio Liliana me devuelve lo que necesito excepto que no
tiene control sobre los ultimos 12 meses, es decir cuando los clientes
tienen mas de 12 consumo las dos potencias mas grande el la sigue buscando
en todas, lo que necesitaria del codigo es limitar las dos potencias


maximas
que esten entre los ultimos 12 meses.

Gracias de antes manos por toda esta ayuda.

Este es el Codigo


Create VIEW Lecturas2PotenciasMayoresAnteriores(
ClienteID,ConsumoID,FechaLectura, Potencia_Punta,Potencia
, PotenciaAnterior1, PotenciaAnterior2,PotenciaAnterior4,
PotenciaAnterior5)
AS
SELECT t1.clienteid,t1.ConsumoID,t1.fecha, t1.potencia_Punta,t1.Potencia,
ISNULL(MAX(t2.potencia_Punta),0),
ISNULL(MAX(t3.potencia_Punta),0),ISNULL(MAX(t4.potencia),0),
ISNULL(MAX(t5.potencia),0)
FROM Ultimos12 t1
LEFT JOIN CONSUMO t2 ON t1.clienteid = t2.clienteid AND t1.fecha >


t2.fecha
LEFT JOIN CONSUMO t3 ON t1.clienteid = t3.clienteid AND t1.fecha >


t3.fecha
and t2.potencia_Punta > t3.potencia_Punta

LEFT JOIN CONSUMO t4 ON t1.clienteid = t4.clienteid AND t1.fecha >


t4.fecha
LEFT JOIN CONSUMO t5 ON t1.clienteid = t5.clienteid AND t1.fecha >


t5.fecha
and t4.potencia > t5.potencia
GROUP BY t1.clienteid, t1.fecha,


t1.potencia_Punta,t1.ConsumoID,t1.Potencia


CREATE view CalculosPotencias
As
SELECT ClienteID
, ConsumoID
, FechaLectura
, Potencia_Punta
, PotenciaAnterior1
, PotenciaAnterior2
, Potencia
, PotenciaAnterior4
, PotenciaAnterior5
, CASE WHEN PotenciaAnterior1 = 0 OR PotenciaAnterior2 = 0 THEN
Potencia_Punta
WHEN (PotenciaAnterior2 + PotenciaAnterior1) / 2 <


Potencia_Punta
THEN
Potencia_Punta
ELSE CONVERT(DEC(10,2), (PotenciaAnterior2 + PotenciaAnterior1) /


2)
END AS PotenciaPunta
, CASE WHEN PotenciaAnterior4 = 0 OR PotenciaAnterior5 = 0 THEN


Potencia
WHEN (PotenciaAnterior4 + PotenciaAnterior5) / 2 < Potencia THEN
Potencia
ELSE CONVERT(DEC(10,2), (PotenciaAnterior5 + PotenciaAnterior4) /


2)
END AS Potencia1
FROM Lecturas2PotenciasMayoresAnteriores






"Javier Loria" wrote in message
news:
> Hola Julio:
> Bien, estuve leyendo tus posteos previos y las respuestas de


Liliana,
> todavia creo que no estoy entiendo el problema, pero veamos a ver si me
> acerco a la solucion, asumo SQL 2000, si es SQL 7.0 se puede hacer pero
> requiere consultas anidadas que hacen un poco mas dificil de leer el
codigo.
> Numeremos otra vez las lecturas pero basadas en la potencia y en la
> limitacion de las fechas. Esto descarta el uso de la vistas ya que el
GROUP
> BY no permitira usar las filas originales. Entonce podemos crear la
> siguiente funcion en linea:
> => > CREATE FUNCTION LecturasConsumoNumeradas(
> @FechaInicial SMALLDATETIME
> , @FechaFinal SMALLDATETIME)
> RETURNS TABLE
> AS
> RETURN SELECT C1.ClienteID
> , C1.Fecha
> , C1.Potencia
> , COUNT(*) AS NumLectura
> FROM Consumo AS C1
> JOIN Consumo AS C2
> ON C1.ClienteIDÂ.ClienteID
> AND (C1.Potencia<C2.Potencia
> OR (C1.PotenciaÂ.Potencia AND C1.Fecha<Â.Fecha))
> WHERE C1.Fecha BETWEEN @FechaInicial AND DATEADD(day,-1,@FechaFinal)
> AND C2.Fecha BETWEEN @FechaInicial AND DATEADD(day,-1,@FechaFinal)
> GROUP BY C1.ClienteID
> , C1.Fecha
> , C1.Potencia
> HAVING COUNT(*)<=2
> => > Esta funcion devuelve las 2 lecturas mas altas de Potencia, en un
rango
> de Fechas. Revisa que no toma en cuenta la Fecha Final (le resta un 1
dia),
> esto con el fin de que no se incluya la ultima lectura en el rango. No
deje
> construido en la consulta los 12 meses porque me parece una regla de
negocio
> que deberia ir en componentes y no en una funcion de BD. Si no estas de
> acuerdo conmingo y quieres simplificarlo puedes eliminar la variable
> FechaFinal y reemplazarla con DATEADD(year, -1, @FechaFinal).
> Al ordenar por Potencia es probable que encontremos muchos


"empates",
> entonces usamos la fecha para desempatar, usando la ultima lectura. Por
esto
> el JOIN tiene un OR.
> Revisa tambien que NO USE una funcion ESCALAR, una funcion ESCALAR


que
> devuelva un valor basado en el Codigo de Cliente, seria desastroso para


el
> desempeno, una funcion en-linea funciona como una vista con parametros.
> Si esto esta correcto, entonces podrias hacer:
> => > SELECT C.ClienteID
> , C.Fecha
> , C.Potencia
> , COALESCE(MAlto1.Potencia,0) AS Potencia1
> , COALESCE(MAlto2.Potencia,0) AS Potencia2
> FROM Consumo AS C
> LEFT JOIN LecturasConsumoNumeradas('2003-04-01', '2004-04-01') AS MAlto1
> ON C.ClienteID=MAlto1.ClienteID
> AND MAlto1.NumLectura=1
> LEFT JOIN LecturasConsumoNumeradas('2003-04-01', '2004-04-01') AS MAlto2
> ON C.ClienteID=MAlto1.ClienteID
> AND MAlto2.NumLectura=2
> WHERE C.Fecha='2004-04-01'
> => > Espero te sirva,
>
> Javier Loria
> Costa Rica
> Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
> que pueda ser copiado y pegado al Query Analizer.
> La version de SQL y Service Pack tambien ayuda
>
> "Julio" wrote in message
> news:#
> > Estuve revisando el codigo, el average de las potencia la esta


haciendo
> con
> > los dos ultimos meses, deberia de ser con las dos potencias mas


grandes
> sin
> > importar los meses.
> > Donde dice PotenciaPunta es lo mismo que debo hacer con el campo
Potencia
> lo
> > que sucede es que no loa habia especificado.
> >
> > El objectivo es sacar el average de las dos potencias mas grandes y
> > compararla con el consumo del ultimo mes para ver cual se le factura


al
> > cliente.
> >
> >
> >
> > "Julio" wrote in message
> > news:
> > > Asi es, voy a probar el codigo y luego le comento
> > > "Liliana Sorrentino" wrote in


message
> > > news:%23r%
> > > > Mientras levanto mi mandíbula que dio contra el teclado cuando


leía
tu
> > > > respuesta, me permito comentarte que no son los dos meses


anteriores
> los
> > > que
> > > > hay que tener en cuenta, sino las dos lecturas mayores (en


potencia)
> de
> > > las
> > > > anteriores.
> > > > Saludos.
> > > >
> > > > "Javier Loria" escribió en el mensaje
> > > > news:ux#
> > > > > Hola Julio:
> > > > > Vamos a ver porque el problema que planteas es complejo y no
se
> > > > entiendo
> > > > > bien el problema. Unos comentarios iniciales: En mis consultas


me
> voy
> > a
> > > > > olvidar del ConsumoID porque en este caso complican el analisis;
voy
> a
> > > ir
> > > > > por partes por si acaso me pierdo y para que se entienda el


codigo
> > > final;
> > > > y
> > > > > voy a asumir que no solo se requiere el calculo de la ultima
factura
> > > sino
> > > > > que tambien deben poder calcularse los meses anterior.
> > > > > Primero podrias "numerar" las lecturas por cliente, pero de
una
> > > forma
> > > > > que la ultima lectura sea 1, la anterior 2, y asi sucesivamente.
> Esto
> > lo
> > > > > logras con la siguiente vista:
> > > > > => > > > > > CREATE VIEW LecturasConsumoNumeradas(ClienteID
> > > > > , FechaLectura, Potencia, NumLectura)
> > > > > AS
> > > > > SELECT C1.ClienteID
> > > > > , C1.Fecha
> > > > > , C1.Potencia
> > > > > , COUNT(*)
> > > > > FROM Consumo AS C1
> > > > > JOIN Consumo AS C2
> > > > > ON C1.ClienteIDÂ.ClienteID
> > > > > AND C1.Fecha<Â.Fecha
> > > > > GROUP BY C1.ClienteID
> > > > > , C1.Fecha
> > > > > , C1.Potencia
> > > > > => > > > > > Si esto funciona, ahora es muy facil lograr la relacion de los
> meses.
> > > > > => > > > > > CREATE VIEW LecturasConsumo2MesesAnteriores(
> > > > > ClienteID, FechaLectura, NumLectura, Potencia
> > > > > , PotenciaAnterior1, PotenciaAnterior2)
> > > > > AS
> > > > > SELECT LCN.ClienteID
> > > > > , LCN.FechaLectura
> > > > > , LCN.NumLectura
> > > > > , LCN.Potencia
> > > > > , COALESCE(MesAnterior1.Potencia,0) AS PotenciaAnterior1
> > > > > , COALESCE(MesAnterior2.Potencia,0) AS PotenciaAnterior2
> > > > > FROM LecturasConsumoNumeradas AS LCN
> > > > > LEFT JOIN LecturasConsumoNumeradas AS MesAnterior1
> > > > > ON LCN.ClienteID=MesAnterior1.ClienteID
> > > > > AND LCN.NumLectura+1=MesAnterior1.NumLectura
> > > > > LEFT JOIN LecturasConsumoNumeradas AS MesAnterior2
> > > > > ON LCN.ClienteID=MesAnterior2.ClienteID
> > > > > AND LCN.NumLectura+2=MesAnterior2.NumLectura
> > > > > ==> > > > > > Aqui hay varias situaciones implicitas, se da la lectura
> anterior
> > y
> > > si
> > > > > no existe se asume 0, podrias ser que mas bien se debe asumir


NULL
y
> > > > > eliminar el COALESCE. Por ejemplo si el primer mes la potencia


es
10
> y
> > > el
> > > > > segundo mes la potencia es 3 cuanto cobro de potencia: 3 porque


es
> la
> > > > > lectura y no hay 2 anteriores?, 10 porque promedio 10 con nada?


o
5
> > > porque
> > > > > promedio 10 y 0?
> > > > > En todo caso hay te queda para Sumar las 2


potenciasAnteriores
> > > > > dividirlas entre 2 y compararlas con el mes Actual
> > > > > ==> > > > > > SELECT ClienteID
> > > > > , FechaLectura
> > > > > , NumLectura
> > > > > , Potencia
> > > > > , CASE WHEN (PotenciaAnterior2+PotenciaAnterior1)/2<Potencia


THEN
> > > > Potencia
> > > > > ELSE CAST((PotenciaAnterior2+PotenciaAnterior1)/2 AS
> DECIMAL(18,2))
> > > > > END AS PotenciaPunta
> > > > > FROM LecturasConsumo2MesesAnteriores
> > > > > ==> > > > > > Es muy probable que esto pueda resolverse en en una solo
> consulta,
> > > > pero
> > > > > me parece que asi queda mas claro.
> > > > > Si la consulta resulta muy lenta, deberia evaluarse la
condicion
> > de
> > > > > tener que calcular los meses anteriores, ya que se podrian poner
> > > > condiciones
> > > > > para hacerla mucho mas rapida.
> > > > > Saludos,
> > > > >
> > > > > Javier Loria
> > > > > Costa Rica
> > > > > Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
> > > > > que pueda ser copiado y pegado al Query Analizer.
> > > > > La version de SQL y Service Pack tambien ayuda
> > > > >
> > > > >
> > > > > "Julio" wrote in message
> > > > > news:
> > > > > > Hola grupo
> > > > > >
> > > > > > Tengo un problema con algo aqui y quisiera ver si me pueden


dar
> una
> > > mano
> > > > > con
> > > > > > esto.
> > > > > >
> > > > > > Tengo una tabla llamada Consumo la cual es alimentada por un


DTS
> que
> > > > > > introduce todos los datos en ellas, tengo un caso y es el
> siguiente.
> > > > > > Cada vez que se haga un insert en la tabla consumo el campo


que
> dice
> > > > > > Potencia de la tabla Consumo sera igual al average de las dos
> > potencia
> > > > mas
> > > > > > alta en el caso que esta sean mayor que la potencia que se
> inserto,
> > en
> > > > > caso
> > > > > > de ser menor se queda la
> > > > > > potencia que se inserto.
> > > > > >
> > > > > > entonces en la tabla consumo se hace todo el insert sin hacer
> > ninguna
> > > > > > comparacion es decir el campo potencia se inserta tal como
viene,
> > > luego
> > > > > creo
> > > > > > una vista llamada ConsumoAP para hacer los calculos.
> > > > > >
> > > > > > Para que se pueda entende mejor este proyecto es para facturar
la
> > > > energia
> > > > > > electrica consumida por un usuario,como ya saben todos los


meses
> se
> > le
> > > > > cobra
> > > > > > lo que consumieron y si la potencia que consumieron es mayor


que
> las
> > > dos
> > > > > mas
> > > > > > alta entonces se le cobra esa, de lo contario se
> > > > > > le cobraria el average.
> > > > > >
> > > > > > En la vista ConsumoAP quiero sustituir el select que dice


Select
> > > > > > Max(Potencia) por el valor de de lo explicado anteriormente.
> > > > > >
> > > > > > Esta son las tablas:
> > > > > >
> > > > > > Tabla de consumo :
> > > > > >
> > > > > > CREATE TABLE [dbo].[Consumo] (
> > > > > > [ConsumoID] [int] IDENTITY (1, 1) NOT NULL ,
> > > > > > [ClienteID] [int] NOT NULL ,
> > > > > > [Fecha] [datetime] NOT NULL ,
> > > > > > [Energia] [decimal](18, 2) NULL ,
> > > > > > [Reactiva] [decimal](18, 2) NULL ,
> > > > > > [Potencia] [decimal](18, 2) NULL ,
> > > > > > [Potencia_punta] [decimal](18, 2) NULL ,
> > > > > > [Mes] AS (case (datepart(month,[fecha])) when '01' then


'Enero'
> > when
> > > > '02'
> > > > > > then 'Febrero' when '03' then 'Marzo' when '04' then 'Abril'
when
> > '05'
> > > > > then
> > > > > > 'Mayo' when '06' then 'Junio' when '07' then 'Julio' when '08'
> then
> > > > > 'Agosto'
> > > > > > when '09' then 'Septiembre' when '10' then 'Octubre' when '11'
> then
> > > > > > 'Noviembre' when '12' then 'Diciembre' end) ,
> > > > > > [Año] AS (datename(year,[fecha])) ,
> > > > > > [FechaInsertacion] [datetime] NULL ,
> > > > > > [Usuario] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS
> NULL
> > > > > > ) ON [PRIMARY]
> > > > > >
> > > > > > Esta es la vista :
> > > > > >
> > > > > > CREATE VIEW ConsumoAP
> > > > > > AS
> > > > > > SELECT Consumo.ConsumoID
> > > > > > , Consumo.Fecha
> > > > > > , Consumo.ClienteID
> > > > > > , Consumo.Mes
> > > > > > , Consumo.Año
> > > > > > , Consumo.Reactiva
> > > > > > , Consumo.Energia
> > > > > > , MAX(C2.Fecha) AS FechaConsumoAnterior
> > > > > >
> > > > > > , (Select max(Potencia) From Consumo C2 Where


C2.Clienteid
> > > > > > > Consumo.ClienteId)[Max_Potencia]
> > > > > >
> > > > > > , (Select max(Potencia_Punta) From Consumo C2 Where
> > > C2.Clienteid
> > > > > > > > > > > Consumo.ClienteId)[Max_PotenciaPunta]
> > > > > > FROM Consumo
> > > > > > LEFT JOIN Consumo AS C2
> > > > > > ON Consumo.ClienteIdÂ.ClienteID
> > > > > > AND Consumo.Fecha>C2.Fecha
> > > > > > GROUP BY Consumo.ConsumoID
> > > > > > , Consumo.Fecha
> > > > > > , Consumo.ClienteID
> > > > > > , Consumo.Mes
> > > > > > , Consumo.Año
> > > > > > , Consumo.Reactiva
> > > > > > , Consumo.Energia
> > > > > >
> > > > > >
> > > > > >
> > > > > > ejemplo
> > > > > >
> > > > > >
> > > > > > Tabla Consumo
> > > > > >
> > > > > > Consumoid ClienteID Fecha Potencia
> > > > > > 1 1 01/01/04 5
> > > > > > 2 1 01/02/04 10
> > > > > > 3 1 01/03/04 6
> > > > > > 4 1 01/04/04 7
> > > > > >
> > > > > >
> > > > > >
> > > > > > Vista quedaria asi
> > > > > >
> > > > > > Consumoid ClienteID Fecha Potencia
> > > > > > 1 1 01/01/04 5
> > > > > > 2 1 01/02/04 10
> > > > > > 3 1 01/03/04 7.5
> > > > > > 4 1 01/04/04 8
> > > > > >
> > > > > >
> > > > > > Si observa para la fecha 01/04/04 en la tabla consumo la
potencia
> > fue
> > > > > igual
> > > > > > a 7, pero la vista tiene 8 ya que el promedio de las dos
potencias
> > mas
> > > > > alta
> > > > > > de la tabla consumo fueron igual 8 que es mayor que 7. Lo


mismo
> > sucede
> > > > en
> > > > > la
> > > > > > fecha 01/03/04
> > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>


Respuesta Responder a este mensaje
#12 Javier Loria
30/08/2004 - 16:12 | Informe spam
Hola Julio:
Umm. Nope, el problema de mi codigo es que tiene un error en el segundo
JOIN repite MAlto1 en lugar de Malto2. Puedes probra con:
SELECT C.ClienteID
, C.Fecha
, C.Potencia
, COALESCE(MAlto1.Potencia,0) AS Potencia1
, COALESCE(MAlto2.Potencia,0) AS Potencia2
FROM Consumo AS C
LEFT JOIN LecturasConsumoNumeradas('2003-04-01', '2004-04-01') AS MAlto1
ON C.ClienteID=MAlto1.ClienteID
AND MAlto1.NumLectura=1
LEFT JOIN LecturasConsumoNumeradas('2003-04-01', '2004-04-01') AS MAlto2
ON C.ClienteID=MAlto2.ClienteID
AND MAlto2.NumLectura=2
WHERE C.Fecha='2004-04-01'
== A ver si este es el resultado deseado?
Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda
"Julio" wrote in message
news:
Hola Javier, Estuve probando el codigo pero solo me devuelve esto para un
solo cliente.
El codigo que me envio Liliana me devuelve lo que necesito excepto que no
tiene control sobre los ultimos 12 meses, es decir cuando los clientes
tienen mas de 12 consumo las dos potencias mas grande el la sigue buscando
en todas, lo que necesitaria del codigo es limitar las dos potencias


maximas
que esten entre los ultimos 12 meses.

Gracias de antes manos por toda esta ayuda.

Este es el Codigo


Create VIEW Lecturas2PotenciasMayoresAnteriores(
ClienteID,ConsumoID,FechaLectura, Potencia_Punta,Potencia
, PotenciaAnterior1, PotenciaAnterior2,PotenciaAnterior4,
PotenciaAnterior5)
AS
SELECT t1.clienteid,t1.ConsumoID,t1.fecha, t1.potencia_Punta,t1.Potencia,
ISNULL(MAX(t2.potencia_Punta),0),
ISNULL(MAX(t3.potencia_Punta),0),ISNULL(MAX(t4.potencia),0),
ISNULL(MAX(t5.potencia),0)
FROM Ultimos12 t1
LEFT JOIN CONSUMO t2 ON t1.clienteid = t2.clienteid AND t1.fecha >


t2.fecha
LEFT JOIN CONSUMO t3 ON t1.clienteid = t3.clienteid AND t1.fecha >


t3.fecha
and t2.potencia_Punta > t3.potencia_Punta

LEFT JOIN CONSUMO t4 ON t1.clienteid = t4.clienteid AND t1.fecha >


t4.fecha
LEFT JOIN CONSUMO t5 ON t1.clienteid = t5.clienteid AND t1.fecha >


t5.fecha
and t4.potencia > t5.potencia
GROUP BY t1.clienteid, t1.fecha,


t1.potencia_Punta,t1.ConsumoID,t1.Potencia


CREATE view CalculosPotencias
As
SELECT ClienteID
, ConsumoID
, FechaLectura
, Potencia_Punta
, PotenciaAnterior1
, PotenciaAnterior2
, Potencia
, PotenciaAnterior4
, PotenciaAnterior5
, CASE WHEN PotenciaAnterior1 = 0 OR PotenciaAnterior2 = 0 THEN
Potencia_Punta
WHEN (PotenciaAnterior2 + PotenciaAnterior1) / 2 <


Potencia_Punta
THEN
Potencia_Punta
ELSE CONVERT(DEC(10,2), (PotenciaAnterior2 + PotenciaAnterior1) /


2)
END AS PotenciaPunta
, CASE WHEN PotenciaAnterior4 = 0 OR PotenciaAnterior5 = 0 THEN


Potencia
WHEN (PotenciaAnterior4 + PotenciaAnterior5) / 2 < Potencia THEN
Potencia
ELSE CONVERT(DEC(10,2), (PotenciaAnterior5 + PotenciaAnterior4) /


2)
END AS Potencia1
FROM Lecturas2PotenciasMayoresAnteriores






"Javier Loria" wrote in message
news:
> Hola Julio:
> Bien, estuve leyendo tus posteos previos y las respuestas de


Liliana,
> todavia creo que no estoy entiendo el problema, pero veamos a ver si me
> acerco a la solucion, asumo SQL 2000, si es SQL 7.0 se puede hacer pero
> requiere consultas anidadas que hacen un poco mas dificil de leer el
codigo.
> Numeremos otra vez las lecturas pero basadas en la potencia y en la
> limitacion de las fechas. Esto descarta el uso de la vistas ya que el
GROUP
> BY no permitira usar las filas originales. Entonce podemos crear la
> siguiente funcion en linea:
> => > CREATE FUNCTION LecturasConsumoNumeradas(
> @FechaInicial SMALLDATETIME
> , @FechaFinal SMALLDATETIME)
> RETURNS TABLE
> AS
> RETURN SELECT C1.ClienteID
> , C1.Fecha
> , C1.Potencia
> , COUNT(*) AS NumLectura
> FROM Consumo AS C1
> JOIN Consumo AS C2
> ON C1.ClienteIDÂ.ClienteID
> AND (C1.Potencia<C2.Potencia
> OR (C1.PotenciaÂ.Potencia AND C1.Fecha<Â.Fecha))
> WHERE C1.Fecha BETWEEN @FechaInicial AND DATEADD(day,-1,@FechaFinal)
> AND C2.Fecha BETWEEN @FechaInicial AND DATEADD(day,-1,@FechaFinal)
> GROUP BY C1.ClienteID
> , C1.Fecha
> , C1.Potencia
> HAVING COUNT(*)<=2
> => > Esta funcion devuelve las 2 lecturas mas altas de Potencia, en un
rango
> de Fechas. Revisa que no toma en cuenta la Fecha Final (le resta un 1
dia),
> esto con el fin de que no se incluya la ultima lectura en el rango. No
deje
> construido en la consulta los 12 meses porque me parece una regla de
negocio
> que deberia ir en componentes y no en una funcion de BD. Si no estas de
> acuerdo conmingo y quieres simplificarlo puedes eliminar la variable
> FechaFinal y reemplazarla con DATEADD(year, -1, @FechaFinal).
> Al ordenar por Potencia es probable que encontremos muchos


"empates",
> entonces usamos la fecha para desempatar, usando la ultima lectura. Por
esto
> el JOIN tiene un OR.
> Revisa tambien que NO USE una funcion ESCALAR, una funcion ESCALAR


que
> devuelva un valor basado en el Codigo de Cliente, seria desastroso para


el
> desempeno, una funcion en-linea funciona como una vista con parametros.
> Si esto esta correcto, entonces podrias hacer:
> => > SELECT C.ClienteID
> , C.Fecha
> , C.Potencia
> , COALESCE(MAlto1.Potencia,0) AS Potencia1
> , COALESCE(MAlto2.Potencia,0) AS Potencia2
> FROM Consumo AS C
> LEFT JOIN LecturasConsumoNumeradas('2003-04-01', '2004-04-01') AS MAlto1
> ON C.ClienteID=MAlto1.ClienteID
> AND MAlto1.NumLectura=1
> LEFT JOIN LecturasConsumoNumeradas('2003-04-01', '2004-04-01') AS MAlto2
> ON C.ClienteID=MAlto1.ClienteID
> AND MAlto2.NumLectura=2
> WHERE C.Fecha='2004-04-01'
> => > Espero te sirva,
>
> Javier Loria
> Costa Rica
> Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
> que pueda ser copiado y pegado al Query Analizer.
> La version de SQL y Service Pack tambien ayuda
>
> "Julio" wrote in message
> news:#
> > Estuve revisando el codigo, el average de las potencia la esta


haciendo
> con
> > los dos ultimos meses, deberia de ser con las dos potencias mas


grandes
> sin
> > importar los meses.
> > Donde dice PotenciaPunta es lo mismo que debo hacer con el campo
Potencia
> lo
> > que sucede es que no loa habia especificado.
> >
> > El objectivo es sacar el average de las dos potencias mas grandes y
> > compararla con el consumo del ultimo mes para ver cual se le factura


al
> > cliente.
> >
> >
> >
> > "Julio" wrote in message
> > news:
> > > Asi es, voy a probar el codigo y luego le comento
> > > "Liliana Sorrentino" wrote in


message
> > > news:%23r%
> > > > Mientras levanto mi mandíbula que dio contra el teclado cuando


leía
tu
> > > > respuesta, me permito comentarte que no son los dos meses


anteriores
> los
> > > que
> > > > hay que tener en cuenta, sino las dos lecturas mayores (en


potencia)
> de
> > > las
> > > > anteriores.
> > > > Saludos.
> > > >
> > > > "Javier Loria" escribió en el mensaje
> > > > news:ux#
> > > > > Hola Julio:
> > > > > Vamos a ver porque el problema que planteas es complejo y no
se
> > > > entiendo
> > > > > bien el problema. Unos comentarios iniciales: En mis consultas


me
> voy
> > a
> > > > > olvidar del ConsumoID porque en este caso complican el analisis;
voy
> a
> > > ir
> > > > > por partes por si acaso me pierdo y para que se entienda el


codigo
> > > final;
> > > > y
> > > > > voy a asumir que no solo se requiere el calculo de la ultima
factura
> > > sino
> > > > > que tambien deben poder calcularse los meses anterior.
> > > > > Primero podrias "numerar" las lecturas por cliente, pero de
una
> > > forma
> > > > > que la ultima lectura sea 1, la anterior 2, y asi sucesivamente.
> Esto
> > lo
> > > > > logras con la siguiente vista:
> > > > > => > > > > > CREATE VIEW LecturasConsumoNumeradas(ClienteID
> > > > > , FechaLectura, Potencia, NumLectura)
> > > > > AS
> > > > > SELECT C1.ClienteID
> > > > > , C1.Fecha
> > > > > , C1.Potencia
> > > > > , COUNT(*)
> > > > > FROM Consumo AS C1
> > > > > JOIN Consumo AS C2
> > > > > ON C1.ClienteIDÂ.ClienteID
> > > > > AND C1.Fecha<Â.Fecha
> > > > > GROUP BY C1.ClienteID
> > > > > , C1.Fecha
> > > > > , C1.Potencia
> > > > > => > > > > > Si esto funciona, ahora es muy facil lograr la relacion de los
> meses.
> > > > > => > > > > > CREATE VIEW LecturasConsumo2MesesAnteriores(
> > > > > ClienteID, FechaLectura, NumLectura, Potencia
> > > > > , PotenciaAnterior1, PotenciaAnterior2)
> > > > > AS
> > > > > SELECT LCN.ClienteID
> > > > > , LCN.FechaLectura
> > > > > , LCN.NumLectura
> > > > > , LCN.Potencia
> > > > > , COALESCE(MesAnterior1.Potencia,0) AS PotenciaAnterior1
> > > > > , COALESCE(MesAnterior2.Potencia,0) AS PotenciaAnterior2
> > > > > FROM LecturasConsumoNumeradas AS LCN
> > > > > LEFT JOIN LecturasConsumoNumeradas AS MesAnterior1
> > > > > ON LCN.ClienteID=MesAnterior1.ClienteID
> > > > > AND LCN.NumLectura+1=MesAnterior1.NumLectura
> > > > > LEFT JOIN LecturasConsumoNumeradas AS MesAnterior2
> > > > > ON LCN.ClienteID=MesAnterior2.ClienteID
> > > > > AND LCN.NumLectura+2=MesAnterior2.NumLectura
> > > > > ==> > > > > > Aqui hay varias situaciones implicitas, se da la lectura
> anterior
> > y
> > > si
> > > > > no existe se asume 0, podrias ser que mas bien se debe asumir


NULL
y
> > > > > eliminar el COALESCE. Por ejemplo si el primer mes la potencia


es
10
> y
> > > el
> > > > > segundo mes la potencia es 3 cuanto cobro de potencia: 3 porque


es
> la
> > > > > lectura y no hay 2 anteriores?, 10 porque promedio 10 con nada?


o
5
> > > porque
> > > > > promedio 10 y 0?
> > > > > En todo caso hay te queda para Sumar las 2


potenciasAnteriores
> > > > > dividirlas entre 2 y compararlas con el mes Actual
> > > > > ==> > > > > > SELECT ClienteID
> > > > > , FechaLectura
> > > > > , NumLectura
> > > > > , Potencia
> > > > > , CASE WHEN (PotenciaAnterior2+PotenciaAnterior1)/2<Potencia


THEN
> > > > Potencia
> > > > > ELSE CAST((PotenciaAnterior2+PotenciaAnterior1)/2 AS
> DECIMAL(18,2))
> > > > > END AS PotenciaPunta
> > > > > FROM LecturasConsumo2MesesAnteriores
> > > > > ==> > > > > > Es muy probable que esto pueda resolverse en en una solo
> consulta,
> > > > pero
> > > > > me parece que asi queda mas claro.
> > > > > Si la consulta resulta muy lenta, deberia evaluarse la
condicion
> > de
> > > > > tener que calcular los meses anteriores, ya que se podrian poner
> > > > condiciones
> > > > > para hacerla mucho mas rapida.
> > > > > Saludos,
> > > > >
> > > > > Javier Loria
> > > > > Costa Rica
> > > > > Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
> > > > > que pueda ser copiado y pegado al Query Analizer.
> > > > > La version de SQL y Service Pack tambien ayuda
> > > > >
> > > > >
> > > > > "Julio" wrote in message
> > > > > news:
> > > > > > Hola grupo
> > > > > >
> > > > > > Tengo un problema con algo aqui y quisiera ver si me pueden


dar
> una
> > > mano
> > > > > con
> > > > > > esto.
> > > > > >
> > > > > > Tengo una tabla llamada Consumo la cual es alimentada por un


DTS
> que
> > > > > > introduce todos los datos en ellas, tengo un caso y es el
> siguiente.
> > > > > > Cada vez que se haga un insert en la tabla consumo el campo


que
> dice
> > > > > > Potencia de la tabla Consumo sera igual al average de las dos
> > potencia
> > > > mas
> > > > > > alta en el caso que esta sean mayor que la potencia que se
> inserto,
> > en
> > > > > caso
> > > > > > de ser menor se queda la
> > > > > > potencia que se inserto.
> > > > > >
> > > > > > entonces en la tabla consumo se hace todo el insert sin hacer
> > ninguna
> > > > > > comparacion es decir el campo potencia se inserta tal como
viene,
> > > luego
> > > > > creo
> > > > > > una vista llamada ConsumoAP para hacer los calculos.
> > > > > >
> > > > > > Para que se pueda entende mejor este proyecto es para facturar
la
> > > > energia
> > > > > > electrica consumida por un usuario,como ya saben todos los


meses
> se
> > le
> > > > > cobra
> > > > > > lo que consumieron y si la potencia que consumieron es mayor


que
> las
> > > dos
> > > > > mas
> > > > > > alta entonces se le cobra esa, de lo contario se
> > > > > > le cobraria el average.
> > > > > >
> > > > > > En la vista ConsumoAP quiero sustituir el select que dice


Select
> > > > > > Max(Potencia) por el valor de de lo explicado anteriormente.
> > > > > >
> > > > > > Esta son las tablas:
> > > > > >
> > > > > > Tabla de consumo :
> > > > > >
> > > > > > CREATE TABLE [dbo].[Consumo] (
> > > > > > [ConsumoID] [int] IDENTITY (1, 1) NOT NULL ,
> > > > > > [ClienteID] [int] NOT NULL ,
> > > > > > [Fecha] [datetime] NOT NULL ,
> > > > > > [Energia] [decimal](18, 2) NULL ,
> > > > > > [Reactiva] [decimal](18, 2) NULL ,
> > > > > > [Potencia] [decimal](18, 2) NULL ,
> > > > > > [Potencia_punta] [decimal](18, 2) NULL ,
> > > > > > [Mes] AS (case (datepart(month,[fecha])) when '01' then


'Enero'
> > when
> > > > '02'
> > > > > > then 'Febrero' when '03' then 'Marzo' when '04' then 'Abril'
when
> > '05'
> > > > > then
> > > > > > 'Mayo' when '06' then 'Junio' when '07' then 'Julio' when '08'
> then
> > > > > 'Agosto'
> > > > > > when '09' then 'Septiembre' when '10' then 'Octubre' when '11'
> then
> > > > > > 'Noviembre' when '12' then 'Diciembre' end) ,
> > > > > > [Año] AS (datename(year,[fecha])) ,
> > > > > > [FechaInsertacion] [datetime] NULL ,
> > > > > > [Usuario] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS
> NULL
> > > > > > ) ON [PRIMARY]
> > > > > >
> > > > > > Esta es la vista :
> > > > > >
> > > > > > CREATE VIEW ConsumoAP
> > > > > > AS
> > > > > > SELECT Consumo.ConsumoID
> > > > > > , Consumo.Fecha
> > > > > > , Consumo.ClienteID
> > > > > > , Consumo.Mes
> > > > > > , Consumo.Año
> > > > > > , Consumo.Reactiva
> > > > > > , Consumo.Energia
> > > > > > , MAX(C2.Fecha) AS FechaConsumoAnterior
> > > > > >
> > > > > > , (Select max(Potencia) From Consumo C2 Where


C2.Clienteid
> > > > > > > Consumo.ClienteId)[Max_Potencia]
> > > > > >
> > > > > > , (Select max(Potencia_Punta) From Consumo C2 Where
> > > C2.Clienteid
> > > > > > > > > > > Consumo.ClienteId)[Max_PotenciaPunta]
> > > > > > FROM Consumo
> > > > > > LEFT JOIN Consumo AS C2
> > > > > > ON Consumo.ClienteIdÂ.ClienteID
> > > > > > AND Consumo.Fecha>C2.Fecha
> > > > > > GROUP BY Consumo.ConsumoID
> > > > > > , Consumo.Fecha
> > > > > > , Consumo.ClienteID
> > > > > > , Consumo.Mes
> > > > > > , Consumo.Año
> > > > > > , Consumo.Reactiva
> > > > > > , Consumo.Energia
> > > > > >
> > > > > >
> > > > > >
> > > > > > ejemplo
> > > > > >
> > > > > >
> > > > > > Tabla Consumo
> > > > > >
> > > > > > Consumoid ClienteID Fecha Potencia
> > > > > > 1 1 01/01/04 5
> > > > > > 2 1 01/02/04 10
> > > > > > 3 1 01/03/04 6
> > > > > > 4 1 01/04/04 7
> > > > > >
> > > > > >
> > > > > >
> > > > > > Vista quedaria asi
> > > > > >
> > > > > > Consumoid ClienteID Fecha Potencia
> > > > > > 1 1 01/01/04 5
> > > > > > 2 1 01/02/04 10
> > > > > > 3 1 01/03/04 7.5
> > > > > > 4 1 01/04/04 8
> > > > > >
> > > > > >
> > > > > > Si observa para la fecha 01/04/04 en la tabla consumo la
potencia
> > fue
> > > > > igual
> > > > > > a 7, pero la vista tiene 8 ya que el promedio de las dos
potencias
> > mas
> > > > > alta
> > > > > > de la tabla consumo fueron igual 8 que es mayor que 7. Lo


mismo
> > sucede
> > > > en
> > > > > la
> > > > > > fecha 01/03/04
> > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>


email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida