Ir al contenido principal

Tips semanales #2

Suma de Entradas y Salidas

El problema reside en realizar una suma de dos campos en tablas distintas (entradas y salidas) con un enlace común (artículos), el DER correspondería a lo siguiente:
Modelo de Bodega
Pareciera fácil pero no lo es tanto pues tiene su truco. El código sería el siguiente:

SELECT tipo_articulos_nombre_tipo, articulos_descripcion, 
SUM(cantidad) AS entradas, SUM(cantidad_salida) AS salidas
FROM (
(SELECT
     tipo_articulos.`nombre_tipo` AS tipo_articulos_nombre_tipo,
     articulos.`descripcion` AS articulos_descripcion,
     detalle_entradas.`cantidad` AS cantidad,
 0.0 as cantidad_salida
FROM `articulos` articulos
     LEFT JOIN `detalle_entradas` detalle_entradas ON detalle_entradas.`idarticulo` = articulos.`idarticulo`
     INNER JOIN `entradas` entradas on entradas.identrada=detalle_entradas.`identrada`
     INNER JOIN `tipo_articulos` tipo_articulos ON articulos.`idtipo_articulo` = tipo_articulos.`idtipo_articulo`

ORDER entradas.`fecha_entrada` DESC
)
UNION ALL
(SELECT
     tipo_articulos.`nombre_tipo` AS tipo_articulos_nombre_tipo,
     articulos.`descripcion` AS articulos_descripcion,
     0.0 as cantidad,
     detalle_salidas.`cantidad_despachada` AS cantidad_salida
FROM `articulos` articulos
     INNER JOIN `tipo_articulos` tipo_articulos ON articulos.`idtipo_articulo` = tipo_articulos.`idtipo_articulo`
     LEFT JOIN `detalle_salidas` detalle_salidas  ON detalle_salidas.`idarticulo` = articulos.`idarticulo`
INNER JOIN `salidas` salidas ON detalle_salidas.`idsalida` = salidas.`idsalida`

ORDER BY salidas.`fecha_salida` DESC)
) AS tabla
GROUP BY articulos_descripcion

Me parece que este código es bastante optimizable e incluso puede existir otro enfoque totalmente distinto.
Que coincidan el uso del UNION, subconsulta y agrupación no me da buena espina. Me gustaría saber si es posible hacer esto de otra forma.

Booleanos en PHP

Si quieres convertir un representación en cadena de un boolean, ejem. "yes", "on", "true", "false", etc... a un boolean real, puedes probar esto:

<?php
        $myString = "On";
        $b = filter_var($myString, FILTER_VALIDATE_BOOLEAN);
?>
Esto retornará TRUE para "1", "true", "on" y "yes". De lo contrario retorna FALSE.
 
Escapar los caracteres raros en php para mysql

if(function_exists('mysql_real_escape_string')){
         $_REQUEST = array_map('mysql_real_escape_string', $_REQUEST); 
}

Remover elementos duplicados en un arreglo en PHP: array_unique($array);

$entrada = array("a" => "verde", "rojo", "b" => "verde", "azul", "rojo");
$resultado = array_unique($entrada);
print_r($resultado);
El resultado del ejemplo seria: Array ( [a] => verde [0] => rojo [1] => azul )

 Consulta que devuelve una fila aleatoria de una tabla de MySQL

select * from YOUR_TABLE order by rand() limit 1

Esta consulta funciona bien para tablas con pocos registros (menos de 10,000)  para tablas mas pesadas este enlace provee una mejor forma para seleccionar una fila aleatoria

Comentarios

  1. juan carlos, e tratado de usar la funcion array_map, especificamente en la directiva que das el ejemplo

    if(function_exists('mysql_real_escape_string')){
    $_REQUEST = array_map('mysql_real_escape_string', $_REQUEST);
    }

    pero no me funciona, al verificar la variable que almacena el nuevo arreglo esta vacia. E probado array_map con otras funciones(strtoupper) y funciona bien pero en mysql_real...string nada hermano. talvez me sugeris un camino

    ResponderEliminar
  2. Se me ocurren tres escenarios:
    1. Que el arreglo de entrada ($_REQUEST en este caso)este vacío.
    2. Que la ejecución no esté entrando dentro del if. Lo que significaría que o mysql no esta habilitado o la librería no soporta este método.
    3. Que sí se esté utilizando la función mysql_real_escape_string, pero no exista una conexión abierta, lo que devolvería un false a la variable destino y E_WARNING.
    Intenta descartar estos escenarios.

    ResponderEliminar
  3. en efecto, la solucion tres, es la correcto ayer sabado estuve probando y observe que ese era la razon. upps una pifia. gracias por contestar.

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Enumerar filas en una consulta con MySQL

Supongamos que tenemos tablas con la estructura siguiente: documentos (iddocumento, nombre_documento, url_original, idtipo_documento, idproyecto) proyectos (idproyecto, nombre_proyecto, longitud, unidad_medida) tipo_documentos (idtipo_documento, descripcion_tipo_documento) Tenemos necesidad de hacer una consulta como la siguiente: "Enumerar todos los documentos en la base de datos agrupados por proyecto" Parece fácil, excepto por el término "enumerar", aquí tienes un truquito para que logres enumerar tus consultas: SELECT (@rownum:=@rownum+1) AS rownum, nombre_documento, descripcion_tipo_documento, nombre_proyecto FROM (SELECT @rownum:=0) r, documentos AS d INNER JOIN proyectos AS p ON d.idproyecto = p.idproyecto INNER JOIN tipo_documentos AS td ON d.idtipo_documento = td.idtipo_documento Pero que tal si te piden que enumeres los proyectos con sus correspondientes documentos?. Teniendo lo anterior es un poco mas sencillo SELECT IF(@fila=proyectos.idproyecto,

jQuery DataTables y CodeIgniter

Ajax Source Datatables permite configurar fácilmente el origen de datos de la tabla, para que esta sea generada dinámicamente desde el servidor, así que con CodeIgniter tendríamos el siguiente código public function page(){ $data['pedidos'] = $this->pedidos_model->get_pedidos($this->input->post('iDisplayStart')); define('AJAX_REQUEST', 1);//truco para que en nginx no muestre el debug $TOTAL = $this->pedidos_model->total(); echo json_encode(array('aaData'=>$data['pedidos'], 'iTotalRecords'=>$TOTAL, 'iTotalDisplayRecords'=>$TOTAL, 'sEcho'=>$this->input->post('sEcho'))); } Este método producirá algo parecido a esto: {"iTotalRecords":83099,"iTotalDisplayRecords":83099,"sEcho":"2", "aaData":[{"Id":"85514","num":"86109&q

Personalizando Chrome

Cuando hablo de personalizar no me refiero a cambios en el tema, ni modificar algún comportamiento via la configuración, no, me refiero a obtener el código, modificarlo y compilarlo para crear mi propia "distribución". Así que antes de nada realiza esto: Descargar el codigo: http://dev.chromium.org/developers/how-tos/get-the-code Como compilar: https://code.google.com/p/chromium/wiki/NinjaBuild En caso, como a mi, que necesite una version anterior: https://www.chromium.org/developers/how-tos/get-the-code/working-with-release-branches Me encontré con varios errores cuando trate de descargar la versión 37, aquí está el hilo con las soluciones: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/pmki-Uju6Zs La version 37 no estaba preparada para los cambios que vinieron con Yosemite, un error que encontré:  https://codereview.chromium.org/555163002 https://chromium.googlesource.com/chromium/src.git/+/59c4ad104b6f03af9c9acffc0fd9a42707083390/ba