Ir al contenido


Foto

comparar datos nuevos con datos viejos en la misma tabla


  • Por favor identifícate para responder
9 respuestas en este tema

#1 abraham85

abraham85

    Advanced Member

  • Miembros
  • PipPipPip
  • 128 mensajes

Escrito 01 marzo 2011 - 10:03

Hola gente como estan?  ;)


les comento q tengo una tabla llamada PRECIOS en donde se guardan los precios de un determinado mes y año, la tabla tiene estos campos mas o menos: PRECIOS(mes,anio,precio,prenormalizado).
el campo prenormalizado es el resultado de la multiplicacion de (precio*factor) pero eso no tiene mucha importancia en el caso.


el tema es q yo tengo q calcular la variacion del precio del mes actual con respecto al mes anterior...y si esta variacion es mayor a 5 o menos a -5 entonces  la tengo q mostrar en un reporte, pero eso no me interesa....me interesa mas el hecho de q me puedan ayudar con la consulta SQL, lo del reporte ya lo tengo armado.  (h)


ejemplo :
mes anio precio prenormalizado
3    2010  5.3      2.3
4    2010  2.1      1.1


en este caso tendria q calcular la variacion entre el mes 3 y 4...la formula para calcular la variacion es :
preciomesactual/preciosmesanterior)*100)-100 ---> quedaria asi --->  (5.3)/(2.1))*100)-100 ...si es >5 entonces la muestro.
el dato q a mi me dan es el mes y anio actual...en este caso me dan como entrada de informacion mes=4 y anio=2010
el tema es q nose como hacer la consulta SQL...como puedo obtener y comparar los valores??? :s :s :s :s :s


se entiende???  :(


un abrazo amigos!!
  • 0

#2 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.484 mensajes
  • LocationMallorca

Escrito 02 marzo 2011 - 04:24

Hola.

Puede utilizar dos subconsultas.

¿ Que base de datos utilizas ? (es que los dialectos SQL son ligeramente distintos).

Saludos.
  • 0

#3 abraham85

abraham85

    Advanced Member

  • Miembros
  • PipPipPip
  • 128 mensajes

Escrito 02 marzo 2011 - 07:01

Hola marc!


stoy usando sql server 2005  (h)


a los dos subconsultas te refieres a consultas anidadas?  :s :s


Gracias.
  • 0

#4 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.484 mensajes
  • LocationMallorca

Escrito 02 marzo 2011 - 10:27

Hola.

Sí, en efecto, me refiero a consultas anidadas.

No estoy muy puesto con SQL Server, literalmente no lo uso desde el siglo pasado XD. Así que en plan sencillo, yo a la consulta le pasaría dos parámetros : el mes actual y el mes anterior (en Delphi es fácil de calcular), y luego solo necesitas utilizar una consulta con dos subconsultas :

Por ejplo, ¿ tienes una tabla con solo un registro ?, yo para estos casos en que quiero hacer una consulta con un solo resultado, utilizo una tabla CONFIG, que sé que solo tiene un registro :

select
  (((select PRECIO from VALORES where ANIO = :anio_actual and MES = :mes_actual) /
    (select PRECIO from VALORES where ANIO = :anio_anterior and MES = :mes_anterior)) * 100) - 100
  as NORMALIZADO
from
  CONFIG


Saludos.
  • 0

#5 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 02 marzo 2011 - 11:51

Hola,

A mi humilde parecer, creo que lo más adecuado a este caso es generar un procedimiento almacenado. Si la idea es generar una consulta en la que se vea el precio normalizado, mes a mes; es decir algo:

1 - N/A
2 - Normalizar 2/1
3 - Normalizar 3/2
4 - Normalizar 4/3
etc.

Entonces lo mejor es traer los registros que cumplen la condición y devolver los mismos pero con el agregado del campo Normalizado. La idea básica consiste en ir leyendo registro a registro e ir operando. Se necesita de una variable para tener guardado el precio del registro anterior, naturalmente.

Yo de MS SQL Server no recuerdo nada. Si no te pasaba un código a modo de ejemplo.

Saludos,
  • 0

#6 abraham85

abraham85

    Advanced Member

  • Miembros
  • PipPipPip
  • 128 mensajes

Escrito 03 marzo 2011 - 12:05

Hola marc y Delphuis!    gracias por contestar


Tome tu codigo Marc y trate de adaptarlo a mi tabla en la q tengo muchos registros
por ejemplo:


TABLA PRECIOS


idproducto precio mes  anio  periodo prenormalizado
    111        3.11    3    2010      4          4.11
    222        2.13    3    2010      4          1.44
    333        2.55    3    2010      4          2.66
    111        2.43    4    2010      1          3.55
    222        4.11    4    2010      1          2.34
    333        5.53    4    2010      1          4.21


PERIODO corresponde al precio recogido en una determinada semana
(periodo = 1 para semana 1 y asi para todas las semanas)
si el precio sufrio una variacion mayor al 5% entonces lo muestro en mi reporte
para eso tengo q comparar el precio del mes 3, anio =2010  y periodo =4 (semana 4)
con el precio del mes =4, anio 2010 y periodo = 1 (semana 1 del mes nuevo)


estoy tratando de adaptar este codigo


SELECT
  prenormalizado
FROM
  precios
where ((((SELECT PRECIO FROM precios WHERE ANIO = 2010 AND MES = 12 and periodo=1) /
    (SELECT PRECIO FROM precios WHERE ANIO = 2010 AND MES = 11 and periodo=4)) * 100) - 100 )  > 5


me arroja el siguiente mensaje :


Mens. 512, Nivel 16, Estado 1, Línea 1
La subconsulta ha devuelto más de un valor, lo que no es correcto cuando va a continuación
de =, !=, <, <=, >, >= o cuando se utiliza como expresión.


Entiendo q se refiere a que por le primera consulta me trae muchos precios que cumplen esa condición 
y lo mismo con la segunda subconsulta.


Pero entonces como hago? perdon Marc pero no entendi bien eso de Usar otra tabla CONFIG.


Espero me puedan ayudar. Yo seguire investigando y probando. Gracias


SAludos   
  • 0

#7 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 03 marzo 2011 - 12:47

Hola abraham85.
Disculpa que sea un poco pesado pero te lo pregunto nuevamente ¿Es necesario llevar un informe de los precio normalizados período a período para cada producto? ¿O esperas que el informe solo muestre una normalización para un producto y período en particular?

Si es lo primero entonces es de esperar que el informe esté compuesto de muchos registros. Podría hablarse de un único registro para el segundo caso.

Voy a suponer que se trata del primero. Y te voy a dar unas guías; para que lo puedar llevar a MS SQL Server. Demás está decir que considero oportuno hacerlo por medio de un SP.

1) Traer la consulta de precios ordenada por productos, mes (asc) y período (asc). De este modo tendremos las cosas más fácil para hacer la operatoria ya que los registros a comparar estarán uno seguido del otro.

2) Para esa consulta exploramos registro a registro, para cada producto:
2.1. Para el primer registro el campo Normalizado no puede calcularse, es N/A. Esto es fácil de ver sabiendo que no hay un registro anterior con que comparar. Guardamos el valor de PreNormalizado en una variable temporal Valor1. No hay más que hacer, nos vamos al siguiente registro.
2.2. Leemos el campo PreNormalizado del registro actual y lo guardamos en Valor2.
2.3. Calculamos:

Normal = ((Valor1/Valor2)*100) - 100

2.4. En el campo Normalizado almacenamos dicho valor Normal. Seguidamente hacemos que Valor1 asuma el valor de Valor2. y nos vamos al siguiente registro.
3. Repetimos paso 2.2 a 2.4 hasta legar al siguiente producto. En este punto debemos "limpiar" las variables para iniciar de nuevo el proceso descripto anteriormente. Es decir, cuando ProductoActual <> ProductoAnterior.

Este SP puede devolver los mismos registros de la consulta inicial, simplemente le agrega un campo extra para calcular el valor del precio normalizado.

Sólo nos resta invocarlo:

Select * from ProcedimientoNormalizar()


E incluso esto nos permite filtrarlos. Como dices que te interesa aquellos cuya normalización supere los 5% basta con ponerle un where:

Select * from ProcedimientoNormalizar() where Normalizado >= 0.05


El SP incluso se puede modificar para trabajar con un producto en particular (lo que haría más fácil la implementación ya que no requiere de evaluaciones previas para comprobar si comienza un nuevo producto). El SP puede recibir como parámetro el ID del producto y la consulta incluiría un where IDProducto = ID.

Select * from ProcedimientoNormalizar(ID) where Normalizado >= 0.05

 

Espero al menos haber dado un norte.

Saludos,
  • 0

#8 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.484 mensajes
  • LocationMallorca

Escrito 03 marzo 2011 - 01:41

Hola Abraham.

Di por entendido que el caso que buscabas es el segundo de los que detalla Delphius (una única normalización para un producto y un periodo concreto). Por eso las subconsultas solo devolverían un valor, y no tendrías ese error.

La sugerencia de Delphius es muy adecuada para lo que buscas.

Puedes también intentar conseguirlo en una consulta con consultas anidadas, pero va a ser un poco compleja de escribir y explicar (tienes que utilizar alias para los nombres de la tabla precios, puesto que la consulta exterior y interior de la subconsulta se refieren a la misma tabla).

A la vista de lo que he entendido hasta ahora, ¿ que te parece algo así ?

SELECT
  actual.idproducto, actual.prenormalizado
FROM
  precios actual
where
  actual.anio = 2010 and actual.mes = 12 and actual.periodo = 1 and
  (((actual.precio /
    (SELECT
        anterior.precio
      FROM
        precios anterior
      WHERE
        anterior.idproducto = actual.idproducto and
        anterior.anio = 2010 and anterior.mes =  11 and anterior.periodo = 4)) * 100) - 100) > 5

  • 0

#9 abraham85

abraham85

    Advanced Member

  • Miembros
  • PipPipPip
  • 128 mensajes

Escrito 07 marzo 2011 - 04:40

hola gente q tal? :)


gracias a las ayudas de delphius y marc...hize un mezcla entre lo q me dijeron... ;)
me quedo este codigo casi FINAL  ...este va en SP ya q se repite cada vez por semana sobre la misma tabla (y)



select *
from
  precios as raiz
where
  raiz.mes=12 and raiz.anio=2010 and raiz.periodo=1 and raiz.idmarca=
(
SELECT
  actual.idmarca
FROM
  precios as actual
WHERE
  actual.anio = 2010 AND actual.mes = 12 AND actual.periodo = 1 AND
  actual.idmarca=raiz.idmarca and actual.idneg=raiz.idneg and
  ((((actual.precio /
    (SELECT
        anterior.precio
      FROM
        precios as anterior
      WHERE
        anterior.idmarca = actual.idmarca AND anterior.idneg=actual.idneg and
        anterior.anio = 2010 AND anterior.mes =  11 AND anterior.periodo = 4  )) * 100) - 100) > 5 ) )


la consulta me devuelve los productos q sufrieron una variacion del precio mayor al 5% con respecto al mes anterior. ;)
pero tambine quisiera q me muestre los productos q tubieron una variacion menor al -5%
pero nose como "injertar" esa condicion en la consulta de arriba  : : 
habia pensado en hacer otra consulta con el  "< -5" pero nose  :(

Spero me puedan ayudar...un aBrazo  :(
  • 0

#10 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.484 mensajes
  • LocationMallorca

Escrito 08 marzo 2011 - 02:22

Hola.

Haz la misma consulta, pero evaluando que el valor absoluto de la variación sea mayor que 5. Así identificarás tanto las variaciones > 5 como < -5.

Creo que para ello en SQL Server tienes la función ABS().

Saludos.
  • 0




IP.Board spam blocked by CleanTalk.