Comunidad de diseño web y desarrollo en internet online

Consulta, Subconsulta, Cron job

Citar            
MensajeEscrito el 28 May 2007 06:05 pm
Holas

Necesito hacer un Cron Job que se ejecute mensualmente con una consulta, que va mas o menos así:

Tengo una tabla de usuarios, con 267 usuarios, cada usuario tiene asignada una cuota diferente (es un condominio de parcelas, cada usuario paga una cuota según el metraje de su parcela), y tengo una tabla de movimientos (cobros, pagos, etc.).

Necesito insertar en la tabla de movimientos, un registro por cada usuario, con la fecha, el monto de la cuota (sacado de la tabla de usuarios), el tipo de movimiento, y el id del usuario (también sacado de la tabla de usuarios).

Quizás con algún tipo de loop en PHP lo podría hacer, pero no creo que sea lo más eficiente, y no se si una sub-consulta me sirva (tengo mysql 4.1).

Alguna sugerencia? :?

Por Ramm

BOFH

3152 de clabLevel

6 tutoriales
8 articulos

Genero:Masculino   Bastard Operators From Hell REC Héroes

London, UK

firefox
Citar            
MensajeEscrito el 28 May 2007 09:15 pm
Yo pienso que en la tabla de los usuarios tambien tienes que tener los columnas largo y ancho.- Ademas deberias tener una tabla con las columna mesaño(data) valorm3 en donde pones el valor para un detarminado mes Ej:

Código :

idus  Usuario       ancho   largo
1   calle8nro150     20       30

valormensual
id   mesaño    valorm3
1   2007-05      1300


movimientos
idmesaño     idus     montocanselado
  1            1        (20*30)*1300

La tabla movimiendos tendrias que actualizarla al momento que algun usuario te cansele.-
Crear una pagina con los usuarios , el valor de la cuota de mes (si esta canselada o no) y un boton canselar.-
Al momento de canselar agregar un nuevo campo a la tabla movimientos.-
Vas a tener que hacer una consulta del estilo
$query= "select * from (usuario left join movimientos using (idusuario)) left join valor mensual on movimiento.idmesaño=valormensual.id and mesaño=".$mesañocorrespondiente
Donde $mesañocorrespondiente= 2007-05

Por york3rs

Claber

561 de clabLevel

1 tutorial

Genero:Masculino  

LA___Chile

msie
Citar            
MensajeEscrito el 28 May 2007 10:10 pm
La parte de mostrar los datos se como hacerla, lo que necesito es automatizar el ingreso de los registros de cobro, que son mensuales fijos.

Lo de largo y ancho no va porque las parcelas no son cuadradas, tienen formas irregulares, además que las cuotas están redondeadas, que además están definidas para cada usuario, y cambian una vez al año, asi que prefiero guardar cada registro con el monto.

Lo que me jode es como guardar en una misma operacion un registro para cada usuario con su ID y so cuota en la tabla de movimientos.

Por Ramm

BOFH

3152 de clabLevel

6 tutoriales
8 articulos

Genero:Masculino   Bastard Operators From Hell REC Héroes

London, UK

firefox
Citar            
MensajeEscrito el 28 May 2007 10:56 pm
Esta Carb0n...¿Has intentado con un procedimientoen SQL?.

Por Darel

725 de clabLevel

5 tutoriales

 

I'm a human

firefox
Citar            
MensajeEscrito el 28 May 2007 11:19 pm
Yo no encuentro tan dificil, no se para que vas a ingresar el valor a pagar por cada usuario en la tabla movimientos siendo que aun no pagan, por lo que tengo entendido eso equivale a un ingreso, y eso se genera al momento de canselar.- Pienso que tienes que clarificar bien el procedimiento que deseas generar.-

Por york3rs

Claber

561 de clabLevel

1 tutorial

Genero:Masculino  

LA___Chile

msie
Citar            
MensajeEscrito el 28 May 2007 11:48 pm

york3rs escribió:

...no se para que vas a ingresar el valor a pagar por cada usuario en la tabla movimientos siendo que aun no pagan, por lo que tengo entendido eso equivale a un ingreso, y eso se genera al momento de canselar...


En este caso paguen o no, hay que registrar mensualmente la cuota, ya que si no la pagan, la deben. ademas, mucha gente suele pagar montos que no corresponden a la cuota, puede ser mas, puede ser menos, asi que necesito ir guardando por un lado las deducciones y por otro las asignaciones. y sacar la cuenta.

Mi idea de ir guardando el total de la deuda, es poder mostrarla directamente en cualquier momento con consultas sencillas, en vez de sacar la cuenta de un monton de registros solo para ver cuanto se debe en x momento.

Darel, no se a que te refieres :crap:

Gracias por las sugerencias

Por Ramm

BOFH

3152 de clabLevel

6 tutoriales
8 articulos

Genero:Masculino   Bastard Operators From Hell REC Héroes

London, UK

firefox
Citar            
MensajeEscrito el 29 May 2007 01:21 am
Ya no se si me confundiste más con tu segundo post o aligeraste un poco el trabajo. A lo que entendí, Necesitas saber pasando el último día del mes, quien no ha pagado, y quieres que se especifique en la tabla de movimientos. Creo que lo que necesitas es algo más sencillo a lo que estoy percibiendo :[. Bueno, Vaya que he pensado bastante en como pasar los registros de tu tabla de clientes los movimientos y no se me ocurre otra cosa que un procedimiento en SQL. Verás, probé con un bucle while pero al parecer mi versión del SQL no la soporta. Y ahora con tu último post me viene a la mente una idea más clara (tal vez), Creo que si lo que quieres es no realizar consultas engorrosas, puedes crear una vista:

Código :

CREATE VIEW DEUDORES AS
[Aqui va la consulta que saca los adeudos]

De esa manera, creas una tabla virtual, en donde cada vez que la llames:

Código :

SELECT * FROM DEUDORES

aparecerán automáticamente los deudores.
Ahora bien, No puedo gernerarte las condiciones que irían en el código de creación de la vista porque tendría que comparar fechas o si manejas algún estatus para los movimientos, etc. Sería bueno que postearas toda la estructura de tu tabla para tener una visión general, y verás que a lo mejor, a final de cuentas no necesitas hacer ese guardado masivo.
Y disculpa si escribo y escribo y no resuelvo nada, es que ando fuera de casa, y no tengo el MySQL para hacer pruebas, pero a lo mejor te urge y pues quise orientar un poco.

Por Darel

725 de clabLevel

5 tutoriales

 

I'm a human

msie
Citar            
MensajeEscrito el 29 May 2007 01:23 am
Creo que Darel se refiere a procedimientos almacenados. Pero estos estan implementados desde MySQL 5.0 si mal no recuerdo.

Por Reymond

Claber

1111 de clabLevel

5 tutoriales
1 articulo

Genero:Masculino  

Mobile developer

firefox
Citar            
MensajeEscrito el 29 May 2007 12:21 pm
Creo que no me he explicado bien :crap:

Deudores son TODOS, todos los usuarios deben pagar una cuota al mes. Cada usuario tiene una cuota diferente, que esta guardada junto con sus datos en la tabla usuarios.
Yo necesito hacer algo como esto:

Código :

    $query = "SELECT `id`, `cuota` FROM `usuarios` WHERE `cuota` <> 0;";
    $result = mysql_query($query, $conex);

    while($row = mysql_fetch_array($result)) {  //se supone que este insert se repetira por cada usuario.
        $insert = "INSERT INTO `movimientos` (`fecha`, `monto`, `tipo`, `usuario`) VALUES(NOW(), '".$row['monto']."', 'cuota', '".$row['id']."');";
        mysql_query($insert, $conex);
    }


Mas o menos seria eso, pero por un lado, no se si eso sirve, y por otro, no se si es lo mas eficiente.

No necesito mas que esa consulta, lo demás yo lo tengo ya, como sacar las cuentas, como mostrarlas, todo eso ya esta hecho. Solo necesito saber como hacer esa operación lo más eficientemente posible.

Por Ramm

BOFH

3152 de clabLevel

6 tutoriales
8 articulos

Genero:Masculino   Bastard Operators From Hell REC Héroes

London, UK

firefox
Citar            
MensajeEscrito el 29 May 2007 01:10 pm
Por lo que creo tienes mal modelada tu base de datos, estas generando redundancia de datos.-
O puede ser que no hayas estructurado bien esta operacion, pienso que si la lo almacenas de otra manera seria mucho mas facil.-
Por ejemplo en la tabla Movimientos.-
Debe Haber Cuotapagada...
Debe= al pasar otro mes se deberia revisar los usuarios inpagos y crear un listado de la cuota inpaga
Haber= si al momento de pagar sobremesa la cuota, agregar el sobrete a Haber
Cuotapagada= valor de cuota mes correspondiente.-

Pdta.: Piensa bien como hacer este procedimiento, segun yo no es eficiente.-

Por york3rs

Claber

561 de clabLevel

1 tutorial

Genero:Masculino  

LA___Chile

msie
Citar            
MensajeEscrito el 29 May 2007 01:15 pm
Creo que el último ejemplo es el más sencillo. 267 registros tampoco son muchos, pero no es problema en cuanto a que se pueda quedar tonto el servidor.

Creo que es tu mejor opción, sencilla y sin muchas complicaciones. Quizás haya alguna forma de hacerlo directamente (que lo dudo, porque creo que un insert inserta UN registro y no múltiples, pero eso se lo dejo a los masters)

Por _CONEJO

BOFH

7639 de clabLevel

17 tutoriales
21 articulos

 

firefox
Citar            
MensajeEscrito el 31 May 2007 01:46 pm
:(

NO quiero sonar odioso, pero independientemente de si tengo mal modelada la base de datos o no, debo hacer ese registro mensualmente.

york3rs escribió:

O puede ser que no hayas estructurado bien esta operacion, pienso que si la lo almacenas de otra manera seria mucho mas facil.-
Por ejemplo en la tabla Movimientos.-
Debe Haber Cuotapagada...
Debe= al pasar otro mes se deberia revisar los usuarios inpagos y crear un listado de la cuota inpaga
Haber= si al momento de pagar sobremesa la cuota, agregar el sobrete a Haber
Cuotapagada= valor de cuota mes correspondiente.-


Todo esto no importa, porque haya pagado o no, se haya muerto o no, la cuota del mes en curso DEBE registrarse, y sumarse a la deuda. Si el usuario tiene pagado mas del monto de la cuota no importa, porque debo registrarla de igual forma

Gracias _CONEJO, esperemos a los masters a ver que dicen, (aunque estan desaparecidos)

Por Ramm

BOFH

3152 de clabLevel

6 tutoriales
8 articulos

Genero:Masculino   Bastard Operators From Hell REC Héroes

London, UK

firefox
Citar            
MensajeEscrito el 01 Jun 2007 06:30 am
Sorry ramm, tarde un poco.... Bueno no se como tengas la base de datos estructurada, solo espero que no le hayas hecho caso a aquel "Ingeniero" si se trata de lo mismo.

Ok mira, un loop de 267 iteraciones no es nada, pero si debes tratar de hacerlo lo mejor posible. No te preocupes por las iteraciones que puedas hacer, solo piensa que cuando tienes mas de 1000 usuarios en linea a la vez haces muchisimo más consultas. MySQL soporta eso y mucho más.

La recomendación que te puedo hacer es que como eso será ejecutado con Cron Job no puedes emitir salida html porque nadie la va a ver, pero si puedes crear un archivo historico de la operación (simplemente un archivo de texto), donde se registre el estado en que quedo cada iteracion, algo como: si fue exitosa la operacion, si no lo fue ¿por que no lo fue?, y eso.


saludos

Por Maikel

BOFH

5575 de clabLevel

22 tutoriales
5 articulos

Genero:Masculino   Team Cristalab

Claber de baja indefinida

firefox
Citar            
MensajeEscrito el 01 Jun 2007 05:45 pm
Ramm, el trabajo esta acabando con mi vida. Como sea, pasame el link al post cuando tengas problemas como este. :wink:

Solución 1. The best
si tienes MySQL 5.x, con un store procedure y 3 lineas sql se soluciona, además sería los mas eficiente, también reduciriamos el php a una línea. Si tienes MySQL 5.x me dices y te digo como hacerle

En caso de que no tengas MySQL 5.x, te recomiendo.

Solución 2. The optimized
La verdad que mas que las veces que php entra a una iteración, lo que me preocupa es la enorme cantidad de veces que invocarías mysql_query, eso se puede evitar. Aqui te pongo un ejemplo, como verás se puede hacer un insert de esta forma(así unicamente tendríamos un mysql_query):meditar: :

Código :

INSERT INTO (CAMPO) VALUES (valor1),(valor2),(valor3)


Tu solución(solo es la idea, no quiero decir que exactamente así te funcione):

Código :

   $insert = "INSERT INTO `movimientos` (`fecha`, `monto`, `tipo`, `usuario`) VALUES ";
    while($row = mysql_fetch_array($result)) 
   {  
      //Aqui te recomiendo que los campos tengan valor esperado, para evitar que falle
        $insert .= "\n(NOW(), '".$row['monto']."', 'cuota', '".$row['id']."'),";
    }
   $insert .= substr($insert,0,strlen($insert-1)) . ";";
   
    if( !mysql_query($insert, $conex) )
   {
      //Aqui controla el error y manda el SQL por mail, y demás
   }


Sheers

Por Dano

BOFH

4273 de clabLevel

14 tutoriales
4 articulos
10 ejemplos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Lugar estratégico para vigilarte

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.