Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

insertar datos en dos tablas y realizar calculos

Estas en el tema de insertar datos en dos tablas y realizar calculos en el foro de Mysql en Foros del Web. hola amigos, tengo la siguiente situacion: a una tabla se insertan datos cada minuto y necesito realizar algunos calculos a los datos y que se ...
  #1 (permalink)  
Antiguo 19/12/2014, 14:42
 
Fecha de Ingreso: septiembre-2010
Mensajes: 1.853
Antigüedad: 13 años, 7 meses
Puntos: 6
insertar datos en dos tablas y realizar calculos

hola amigos, tengo la siguiente situacion: a una tabla se insertan datos cada minuto y necesito realizar algunos calculos a los datos y que se inserten en otra tabla esto es posible con mysql?
  #2 (permalink)  
Antiguo 19/12/2014, 15:33
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: insertar datos en dos tablas y realizar calculos

Es posible, pero con tan poca información no podemos agregar nada...
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 20/12/2014, 08:29
 
Fecha de Ingreso: septiembre-2010
Mensajes: 1.853
Antigüedad: 13 años, 7 meses
Puntos: 6
Respuesta: insertar datos en dos tablas y realizar calculos

Esta es la tabla donde se almacenan cada minuto los datos

Código MySQL:
Ver original
  1. CREATE TABLE 'datos' (
  2.   'id' int(11) NOT NULL AUTO_INCREMENT,
  3.   'sucuersal_id'  int(11) NOT NULL,
  4.   'tiempo'  datetime NOT NULL,
  5.   'dato' varchar(1000) NOT NULL,
  6.   PRIMARY KEY ('id')
  7.   )

Este es un registro:
Id:1
sucuersal_id:5
tiempo:2014-12-01 00:00:57
dato:00E +3189915 +0007180 +0008288 +0455 C+1111

y los calculos que debo de realizar son sobre el campo dato 00E +3189915 +0007180 +0008288 +0455 C+1111 y las posiciones [1] (3189915) posiciones [2] (0007180) posiciones [3] (0008288) debo realizar calculos como multiplicaciones y raiz cuadrado.

lo que pretendo es que en una tabla se guarden los datos sin realizar los calculos y en otra guardar los datos calculados y sin utilizar un programa intermedio, es posible con mysql?
  #4 (permalink)  
Antiguo 20/12/2014, 12:02
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: insertar datos en dos tablas y realizar calculos

Todo eso es posible hacer en cualquier DBMS, incluyendo MySQL, aunque habitualmente cuando hay que hacer procesado de datos, y en especial cuando esos procesamientos son rutinarios, se realizan por medio de una combinación entre EVENT y Stored Procedures.
La verdad tu pregunta me sigue resultando algo rara, porque parece que no hubieses trabajado jamás con SP.
Por otro lado, aunque ahora se ve algo más claro, no podría hacerte una propuesta de código porque sigo ignorando qué son esas "posiciones", y qué cálculos debes hacer (las descripcion es demasiado indefinida), y cómo intervienen tales "posiciones", sobre la base de qué reglas.
Yo te sugeriría que empezaras por ver como se hacen los SP en MySQL, y a partir de allí tal vez se pueda resolver.

Como te estás reservando demasiada información, tu pregunta sigue siendo muy abstracta, y no te puedo orientar mejor sin entender la tarea con mas detalle.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 20/12/2014, 19:24
 
Fecha de Ingreso: septiembre-2010
Mensajes: 1.853
Antigüedad: 13 años, 7 meses
Puntos: 6
Respuesta: insertar datos en dos tablas y realizar calculos

gnzsoloyo gracias por responder, para serte sincero no he trabajado con Stored Procedures y EVENTS, por otra parte no me hice entender con lo de las posiciones por tal motivo te voy a explicar: los datos que se insertan cada minuto son:

Id (campo autoincrementable):1
sucuersal_id (campo entero): 5
tiempo (campo timestamp):2014-12-01 00:00:57
dato (campo varchar):00E +3189915 +0007180 +0008288 +0455 C+1111

Los calculos se deben de realizar sobre el campo dato el cual llega de la siguiente manera 00E +3189915 +0007180 +0008288 +0455 C+1111, lo que necesito es guardar cada fragmento anterior al signo + en una columna de la tabla data_procesado y sobre dicho dato realizar calculos.

00E se gurdaria en una columna llamada inicio_trama
3189915 se gurdaria en una columna llamada saldo y aplicar el siguiente calculo: multiplicar por 2
0007180 se gurdaria en una columna llamada voltaje y aplicar el siguiente calculo: dividir por 100
0008288 se gurdaria en una columna llamada bateria y aplicar el siguiente calculo: diividir por 1000
0455 C se gurdaria en una columna llamada codigo_sucursal
1111 se gurdaria en una columna llamada fin trama
  #6 (permalink)  
Antiguo 20/12/2014, 19:51
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: insertar datos en dos tablas y realizar calculos

Bueno, convertir esa trama de datos en una entrada a la otra tabla requiere de usar funciones de cadena para eso. Usualmente te aconsejaría que modificases el proceso que inserta los datos, para que ya ingresen desde origen normalizados. Hacer esto en SQL es algo poco performante.
Ahora bien, asumiendo que no puedes modificarlo, sólo resta crear la query que lo divida. Para eso se usa SUBSTRING_INDEX(), de este modo:
Código MySQL:
Ver original
  1. mysql> SELECT
  2.     ->  TRIM(SUBSTRING_INDEX('00E +3189915 +0007180 +0008288 +0455 C+1111', '+', 1)) valor1,
  3.     ->  CAST(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX('00E +3189915 +0007180 +0008288 +0455 C+1111', '+', 2),'+', -1)) AS UNSIGNED)*2 valor2,
  4.     ->  CAST(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX('00E +3189915 +0007180 +0008288 +0455 C+1111', '+', 3),'+', -1)) AS UNSIGNED)/100 valor3,
  5.     ->  CAST(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX('00E +3189915 +0007180 +0008288 +0455 C+1111', '+', 4),'+', -1)) AS UNSIGNED)/1000 valor4,
  6.     ->  TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX('00E +3189915 +0007180 +0008288 +0455 C+1111', '+', 5),'+', -1)) valor5,
  7.     ->  TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX('00E +3189915 +0007180 +0008288 +0455 C+1111', '+', 6),'+', -1)) valor6
  8.     -> ;
  9. +--------+---------+---------+--------+--------+--------+
  10. | valor1 | valor2  | valor3  | valor4 | valor5 | valor6 |
  11. +--------+---------+---------+--------+--------+--------+
  12. | 00E    | 6379830 | 71.8000 | 8.2880 | 0455 C | 1111   |
  13. +--------+---------+---------+--------+--------+--------+
  14. 1 row in set (0.00 sec)
  15.  
  16. mysql>
Usando algo así se puede crear un insert hacia la segunda tabla con sólo hacer un INSERT... SELECT, como este:
Código MySQL:
Ver original
  1. INSERT INTO tabla(inicio_trama, saldo, voltaje, bateria, codigo_sucursal, fin_trama)
  2.     TRIM(SUBSTRING_INDEX(datos, 1)),
  3.     (CAST(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(datos, '+', 2),'+', -1)) AS UNSIGNED) * 2),
  4.     (CAST(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(datos, '+', 3),'+', -1)) AS UNSIGNED)/100),
  5.     (CAST(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(datos, '+', 4),'+', -1)) AS UNSIGNED)/1000),
  6.     TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(datos, '+', 5),'+', -1)),
  7.     TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(datos, '+', 6),'+', -1))
  8. FROM TABLA;
Esto se podría hacer en un SP, e incluso sería posible en un TRIGGER, pero este segundo caso no es muy perfomante para tu escenario así que te recomiendo no usarlo.
El SP se puede invocar por EVENT para que corra sólo, o bien meter la query en un EVENT, con las condiciones necesarias.
Habría que ver qué condiciones debe cumplir para no duplicar los registros.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 21/12/2014, 21:42
 
Fecha de Ingreso: septiembre-2010
Mensajes: 1.853
Antigüedad: 13 años, 7 meses
Puntos: 6
Respuesta: insertar datos en dos tablas y realizar calculos

gnzsoloyo muy interesante tu solución, me surgen algunas dudas y espero me diculpes si escribo cosas equivocadas: como se haria para que al insertar en la primera tabla se inserte en la segunda? osea que invoca o como se inicia esa segunda inserccion? y tienes razon en la parte de no duplicar registros.
Por otro lado hoy me di cuenta que algunas insercciones no se realizan cada minuto, algunas son cada diez minutos, cada cinco minutos, osea no es un tiempo fijo es variable.
En tu solucion indicas que se podria utilizar EVENT te refieres a El programador de eventos de MySQL ? (http://www.codedrinks.com/event-sche...como-funciona/ ) no se si estoy equivocado pero esa solucion no se adecuaria a mi necesidad ya que seria como si cada 5 minutos por ejemplo se ejecutura y la acción que realiza es insertar en la tabla.

Lo que pretendo es que cuando se haga la insercion en la primera tabla y que mediante alguna funcionalidad de Mysql se inserte en la segunda tabla, es posible?

Última edición por Montes28; 21/12/2014 a las 22:01
  #8 (permalink)  
Antiguo 23/12/2014, 07:58
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: insertar datos en dos tablas y realizar calculos

Montes/Gnzsoloyo, antes que nada, deseandoles una feliz navidad.

Con respecto al tema, creería que la opción mas rápida y eficiente es un trigger. Lo que dice gnzsoloyo en cuanto al performance es cierto si fuera necesario depender del resultado de un query para movilizar el insert actual, sin embargo, veo que esto no es necesario, teniendo en cuenta que el valor a procesar es uno de los parametros de entrada y no es necesario consultarlo.

Tomando como base los calculos que ya gnzsoloyo realizó en el ejemplo, la solución quedaría así:

Código MySQL:
Ver original
  1. CREATE TABLE datos (
  2.   sucuersal_id  int(11) NOT NULL,
  3.   tiempo  datetime NOT NULL,
  4.   dato varchar(1000) NOT NULL,
  5.   PRIMARY KEY (id)
  6.   );
  7.  
  8. CREATE TABLE data_procesado (
  9.   inicio_trama varchar(11) NOT NULL,
  10.   saldo  int(11) NOT NULL,
  11.   voltaje  DECIMAL(14,2) NOT NULL,
  12.   bateria DECIMAL(14,2) NOT NULL,
  13.   codigo_sucursal varchar(20),
  14.   fin_trama varchar(20)
  15.   );
  16.  
  17. DELIMITER $$
  18. CREATE TRIGGER tri_datos
  19.     AFTER INSERT ON datos
  20.     BEGIN
  21.  
  22.     INSERT INTO data_procesado
  23.     VALUES
  24.     (
  25.       TRIM(SUBSTRING_INDEX(NEW.dato, '+', 1)),
  26.       CAST(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(NEW.dato, '+', 2),'+', -1)) AS UNSIGNED)*2,
  27.       CAST(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(NEW.dato, '+', 3),'+', -1)) AS UNSIGNED)/100,
  28.       CAST(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(NEW.dato, '+', 4),'+', -1)) AS UNSIGNED)/1000,
  29.       TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(NEW.dato, '+', 5),'+', -1)),
  30.       TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(NEW.dato, '+', 6),'+', -1))
  31.     );
  32.    
  33. END$$
  34. DELIMITER ;

El parametro de entrada, sería el nuevo valor de la columna dato, y la operación que se realiza es otro INSERT, por lo que no se genera contención en la operación. Si se tratara de un UPDATE o un valor extraido de un SELECT ejecutado al interior del TRIGGER efectivamente esto podría traer serios problemas de performance.

Posterior a esto, se genera un INSERT sobre la tabla datos.

Código MySQL:
Ver original
  1. mysql> INSERT INTO datos (sucuersal_id,tiempo,dato) VALUES(12345,NOW(),'00E +3189915 +0007180 +0008288 +0455 C+1111');
  2. Query OK, 1 row affected (0.08 sec)
  3.  
  4. mysql> SELECT *FROM datos;
  5. +----+--------------+---------------------+---------------------------------------------+
  6. | id | sucuersal_id | tiempo              | dato                                        |
  7. +----+--------------+---------------------+---------------------------------------------+
  8. |  1 |        12345 | 2014-12-23 08:52:25 | 00E +3189915 +0007180 +0008288 +0455 C+1111 |
  9. +----+--------------+---------------------+---------------------------------------------+
  10. 1 row in set (0.01 sec)
  11.  
  12. mysql> select *from data_procesado;
  13. +--------------+---------+---------+---------+-----------------+-----------+
  14. | inicio_trama | saldo   | voltaje | bateria | codigo_sucursal | fin_trama |
  15. +--------------+---------+---------+---------+-----------------+-----------+
  16. | 00E          | 6379830 |      72 |       8 | 0455 C          | 1111      |
  17. +--------------+---------+---------+---------+-----------------+-----------+
  18. 1 row in set (0.00 sec)


Sin embargo, habría que analizar la tabla data_procesado si requiere de algún index que mejore las consultas o de que forma se requiere el uso de dicha tabla.

Saludos
__________________
Without data, You are another person with an opinion.
W. Edwads Deming

Última edición por huesos52; 23/12/2014 a las 08:25
  #9 (permalink)  
Antiguo 23/12/2014, 08:15
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: insertar datos en dos tablas y realizar calculos

Una buena propuesta.
Siendo que lo que nos menciona ahora @Montes28 es que la inserción de datos es sólo cada diez minutos o menos, el impacto de un TRIGGER sería mínimo, por lo que es una buena opción.

Una sola nota respecto al ejemplo usado es que hay que tener en cuenta que los tipos de columna para los datos decimales deben ser DECIMAL, y no INT, y tampoco FLOAT, si es que lo que se quiere es precisión. Probablemente un desliz involuntario.

La tabla destino quedaría mas o menos así:
Código MySQL:
Ver original
  1. CREATE TABLE data_procesado (
  2.   inicio_trama VARCHAR(11) NOT NULL,
  3.   saldo  int(11) NOT NULL,
  4.   voltaje  DECIMAL(14,2) NOT NULL,
  5.   bateria DECIMAL(14,3) NOT NULL,
  6.   codigo_sucursal VARCHAR(20),
  7.   fin_trama VARCHAR(20)
  8.   );
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #10 (permalink)  
Antiguo 23/12/2014, 08:24
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: insertar datos en dos tablas y realizar calculos

Efectivamente!
un desliz involuntario

Corregido!
__________________
Without data, You are another person with an opinion.
W. Edwads Deming

Etiquetas: sql, tabla, tablas
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 02:17.