Page 1 of 1

Consulta en MySQL

PostPosted: Thu Oct 02, 2014 2:34 pm
by acuellar
Amigos como se hace consulta concatenada

Aquí el código, funciona pero muy lento
Code: Select all  Expand view

        Fec_Fin=ctod('31/12/'+cAno)
    Fec_Ini=ctod('01/01/'+cAno)
    tMeses:={"Ene.","Feb.","Mar.","Abr.","May.","Jun.","Jul.","Ago.","Sep.","Oct.","Nov.","Dic."}
    CursorWait()
   oEMPL:=oServer:Query( "SELECT * FROM DATPER ORDER BY CODIGO")
     
 Do While !oEMPL:Eof()
         vDiasT=(oEMPL:FECHARET-Fec_Ini)+1
     
       If vDiasT>365
         vDiasT=365
       Endif
     
       If (vDiasT=365 .or. vDiasT>89) .and. Right(dtos(oEMPL:FECHARET),6)="010101"
          cMESES:="Oct.Nov.Dic."
          MESP1:=cAno+"10";MESP2:=cAno+"11";MESP3:=cAno+"12"
       ElseIf vDiasT>89 .and. Right(dtos(oEMPL:FECHARET),6)!="010101"
           MESP1:=cAno+StrZero(Month(oEMPL:FECHARET)-3,2);MESP2:=cAno+StrZero(Month(oEMPL:FECHARET)-2,2);MESP3:=cAno+StrZero(Month(oEMPL:FECHARET)-1,2)
           cMeses:=tMeses[ Month(oEMPL:FECHARET)-3 ]+tMeses[ Month(oEMPL:FECHARET)-2 ]+tMeses[ Month(oEMPL:FECHARET)-1 ]
       Endif
       
       oPDET:=oServer:Query( "SELECT * FROM PLANIDET WHERE MESP ="+MESP1+" ORDER BY IDEMPL")
       oPDET:Seek( oEMPL:IDEMPL,"IDEMPL" )  
       vMes1:=oPDET1:HBAS+oPDET1:BOANT+oPDET:MTOHEXTR+oPDET:MTOHRECN+oPDET:OTR_ING
       oPDET:=oServer:Query( "SELECT * FROM PLANIDET WHERE MESP ="+MESP2+" ORDER BY IDEMPL")
       oPDET:Seek( oEMPL:IDEMPL,"IDEMPL" )  
       vMes2:=oPDET:HBAS+oPDET:BOANT+oPDET:MTOHEXTR+oPDET:MTOHRECN+oPDET:OTR_ING
       oPDET:=oServer:Query( "SELECT * FROM PLANIDET WHERE MESP ="+MESP3+" ORDER BY IDEMPL")
       oPDET:Seek( oEMPL:IDEMPL,"IDEMPL" )  
       vMes3:=oPDET:HBAS+oPDET:BOANT+oPDET:MTOHEXTR+oPDET:MTOHRECN+oPDET:OTR_ING
   
   /*Con DBF lo tengo así y es bien rápido.
          PDET->( dBseek(MESP1+STR(EMPL->IDEMPL,4)) )
         vMes1:=PDET->HBAS+PDET->BOANT+PDET->MTOHEXTR+PDET->MTOHRECN+PDET->OTR_ING
         dBseek(MESP2+STR(EMPL->IDEMPL,4))
         vMes2:=PDET->HBAS+PDET->BOANT+PDET->MTOHEXTR+PDET->MTOHRECN+PDET->OTR_ING
         dBseek(MESP3+STR(EMPL->IDEMPL,4))
        vMes3:=PDET->HBAS+PDET->BOANT+PDET->MTOHEXTR+PDET->MTOHRECN+PDET->OTR_ING
      */


       If vMes1=0
          vProm=(vMes2+vMes3)/2
       Else
          vProm=(vMes1+vMes2+vMes3)/3
       Endi
       Liq=(vProm/(365+X))*vDiasT
     
       If vDiasT>89
           AADD( aPrima,{ oEMPL:CODIGO,oEMPL:NOMBRE,vDiasT,DTOC(oEMPL:FECHAING),DTOC(oEMPL:FECHARET),cMeses,vMes1,vMes2,vMes3,vPROM,LIQ} )
        Endif
       
    oEMPL:Skip()
 Enddo

 


Gracias por la ayuda

Saludos,

Adhemar

Re: Consulta en MySQL

PostPosted: Thu Oct 02, 2014 4:35 pm
by jrestojeda
Hola,
Yo probaría traerme todo en un mismo Query usando "UNION"

Code: Select all  Expand view
cQuery:="SELECT * FROM PLANIDET WHERE MESP ="+MESP1+" UNION "+;
        "SELECT * FROM PLANIDET WHERE MESP ="+MESP2+" UNION "+;
        "SELECT * FROM PLANIDET WHERE MESP ="+MESP3+;
        "ORDER BY IDEMPL"
oPDET:=oServer:Query(cQuery)


o bien...
Code: Select all  Expand view
cQuery:="SELECT * FROM PLANIDET WHERE MESP ="+MESP1+" OR MESP ="+MESP2+" OR MESP ="+MESP3+" ORDER BY IDEMPL"
oPDET:=oServer:Query(cQuery)


O sea...
No entiendo el sentido de hacer tres querys cuando puedes traerte todo en uno.
Saludos,

Re: Consulta en MySQL

PostPosted: Thu Oct 02, 2014 4:44 pm
by acuellar
Gracias Esteban

Y cómo haría la búsqueda?

Saludos,

Adhemar

Re: Consulta en MySQL

PostPosted: Thu Oct 02, 2014 4:50 pm
by jrestojeda
No entiendo a lo que te refieres...
Conceptualmente en MySql, la busqueda la haces en el mismo query, de modo que te regrese lo que necesitas.
En la condición WHERE agrega todas tus condiciones para que te de el resultado esperado...

Re: Consulta en MySQL

PostPosted: Thu Oct 02, 2014 5:05 pm
by acuellar
El módulo es para el BONO PRIMA

El la tabla PLANIDET están todas las planillas detalladas

Si el empleado trabajó el año pasado mas de 89 días le corresponde.
Se toma como base los meses Oct, Nov y Dic, si fue retirado en julio debe tomar los meses Abr, May y Jun, por lo que la consulta varia.
Tengo que obtener su total ganado de los meses que le corresponde.

Lo que se me ocurre es crear un nuevo campo que tenga IDEMPL+MESPROCESO para poder hacer la búsqueda en una consulta que incluya todos los meses del año pasado.

Gracias, por la ayuda

Saludos,

Adhemar

Re: Consulta en MySQL

PostPosted: Fri Oct 03, 2014 11:34 am
by Daniel Garcia-Gil
Adhemar

Tienes que pensar distinto con mysql, estas viendo las cosas como si siguieras usando DBF, estas usando un motor de base de datos relacional y tienes las herramientas para sacarle todo el jugo... Por lo que veo puedes obtener todo lo que quieres en una sola consulta, claro esta seria un poco mas compleja...

Una de las cosas que resalta es que no necesitas el SEEK, puedes relacionar las dos tablas de una vez en cada una de las tres consultas, (ojo aun hay forma de unir esas tres consultas en una sola sin hacer UNIONES)

si quieres me contactas y te doy una mano despues publicamos el ejemplo de la consulta resultante

Re: Consulta en MySQL

PostPosted: Fri Oct 03, 2014 11:52 am
by jrestojeda
Adhemar
Fijate en la documentación de MySql temas como los JOIN, LEFT OUTER JOIN, GROUP BY, COUNT, etc...
Tal vez entendiendo esos conceptos se te abra el panorama de como continuar.
Saludos,

Re: Consulta en MySQL

PostPosted: Fri Oct 03, 2014 8:24 pm
by joseluisysturiz
Yo lo hago asi sin UNIONES y me trabaja rapidos...saludos... :shock:

Code: Select all  Expand view

         oQry := TDolphinQry():New( "SELECT p.*, c.cli_nom_ape " +;
            "FROM delipollo_pedidos p, delipollo_clientes c " +;
            "WHERE p.cli_telefono = c.cli_telefono " +;
            "ORDER BY ped_num_pedido", oDatos:oConex )
 

Re: Consulta en MySQL

PostPosted: Mon Oct 06, 2014 1:01 pm
by xmanuel
Eduardo hacer eso en SQL es una barbaridad.
Las uniones se hacen para tablas diferentes con estructuras similares.
Esto que tú pones:
Code: Select all  Expand view

cQuery:="SELECT * FROM PLANIDET WHERE MESP ="+MESP1+" UNION "+;
        "SELECT * FROM PLANIDET WHERE MESP ="+MESP2+" UNION "+;
        "SELECT * FROM PLANIDET WHERE MESP ="+MESP3+;
        "ORDER BY IDEMPL"
oPDET:=oServer:Query(cQuery)
 


Se haría así cuando es una unica tabla
Code: Select all  Expand view

cQuery:="SELECT * FROM PLANIDET WHERE MESP IN ( " + MESP1 + ", " + MESP2 + ", " + MESP3 + " ) " + ;
        "ORDER BY IDEMPL"
oPDET:=oServer:Query(cQuery)
 


Aquí es mucho mejo usar la clausula "IN"
Es mucho más fácil y rápido pues sólo se envía una consulta al servidor...
:shock:

Re: Consulta en MySQL

PostPosted: Mon Oct 06, 2014 1:22 pm
by MarioG
Amigos;
creo que esto ya lo pregunte, aunque no obtuve respuesta.
Alguien puede indicar un libro tipo "Aprendiendo MySQL desde cero...", impreso? (o digital. Para mi caso si es MariaDB mejor aun)

Yo he dejado esto, hace tiempo (aunque no me resulto ameno de leer):
https://app.box.com/s/1cese8gyja9ju3ar0kip

Re: Consulta en MySQL

PostPosted: Mon Oct 06, 2014 3:44 pm
by xmanuel
Mario de lo mejorcito que hay en la red es esto: http://mysql.conclase.net/
Aunque la experiencia es lo mejor, buscar en las ayudas de MySQL lo que vayas necesitando...

Re: Consulta en MySQL

PostPosted: Mon Oct 06, 2014 4:22 pm
by MarioG
gracias Manu!

Es bueno teerte "activo" nuevamente por aquí :)

Re: Consulta en MySQL

PostPosted: Mon Oct 06, 2014 5:16 pm
by acuellar
Con la ayuda de Daniel Garcia
He logrado hacer la consulta, un poco compleja:

Code: Select all  Expand view

SELECT
    datper.codigo,
    datper.nombre,
    vmes1.ganado as mes1,
    vmes2.ganado as mes2,
    vmes3.ganado as mes3,
    vdiast.valor as vdias,
    dfecharet.valor as fecharet,
    datper.fechaing,
    datper.fecharet,
    datper.lout
FROM datper
INNER JOIN (
    SELECT
        datper.idempl,
        calcular_diast( datper.lout, datper.fechaing, datper.fecharet, 2013 ) AS valor
    FROM datper
    GROUP BY datper.idempl
) vdiast ON vdiast.idempl = datper.idempl
INNER JOIN (
    SELECT
        datper.idempl,
        calculo_fecha_ret( datper.lout, datper.fechaing, datper.fecharet, 2013 ) AS valor
    FROM datper
    GROUP BY datper.idempl
) dfecharet ON dfecharet.idempl = datper.idempl
LEFT JOIN(
    SELECT
        planidet.idempl,
        planidet.hbas + planidet.boant + planidet.mtohextr + planidet.mtohrecn + planidet.otr_ing as ganado
        FROM planidet
        INNER JOIN (
            SELECT
                datper.idempl,
                CONCAT( LPAD( datper.idempl, 4, '0'), calculo_mesp1( datper.lout, calcular_diast( datper.lout, datper.fechaing, datper.fecharet, 2013 ), calculo_fecha_ret( datper.lout, datper.fechaing, datper.fecharet, 2013 ), 2013 ) ) AS valor
            FROM datper
            GROUP BY datper.idempl
        )  mesp1 ON mesp1.idempl = planidet.idempl
        WHERE SUBSTR(planidet.idmesp,5,4)=2013 AND planidet.idmesp = mesp1.valor
        GROUP BY planidet.idempl
) vmes1 ON vmes1.idempl = datper.idempl
LEFT JOIN(
    SELECT
        planidet.idempl,
        planidet.hbas + planidet.boant + planidet.mtohextr + planidet.mtohrecn + planidet.otr_ing as ganado
        FROM planidet
        INNER JOIN (
            SELECT
                datper.idempl,
                CONCAT( LPAD( datper.idempl, 4, '0'), calculo_mesp2( datper.lout, calcular_diast( datper.lout, datper.fechaing, datper.fecharet, 2013 ), calculo_fecha_ret( datper.lout, datper.fechaing, datper.fecharet, 2013 ), 2013 ) ) AS valor
            FROM datper
            GROUP BY datper.idempl
        )  mesp2 ON mesp2.idempl = planidet.idempl
        WHERE SUBSTR(planidet.idmesp,5,4)=2013 AND planidet.idmesp = mesp2.valor
        GROUP BY planidet.idempl
) vmes2 ON vmes2.idempl = datper.idempl
LEFT JOIN(
    SELECT
        planidet.idempl,
        planidet.hbas + planidet.boant + planidet.mtohextr + planidet.mtohrecn + planidet.otr_ing as ganado
        FROM planidet
        INNER JOIN (
            SELECT
                datper.idempl,
                CONCAT( LPAD( datper.idempl, 4, '0'), calculo_mesp3( datper.lout, calcular_diast( datper.lout, datper.fechaing, datper.fecharet, 2013 ), calculo_fecha_ret( datper.lout, datper.fechaing, datper.fecharet, 2013 ), 2013 ) ) AS valor
            FROM datper
            GROUP BY datper.idempl
        )  mesp3 ON mesp3.idempl = planidet.idempl
        WHERE SUBSTR(planidet.idmesp,5,4)=2013 AND planidet.idmesp = mesp3.valor
        GROUP BY planidet.idempl
) vmes3 ON vmes3.idempl = datper.idempl
WHERE vdias.valor > 89
ORDER BY datper.codigo
 


Creó las funciones en el motor aqui Calcular_diasT
Code: Select all  Expand view

BEGIN
    DECLARE FECHA_FIN DATE;
    DECLARE FECHA_MED DATE;
    DECLARE FECHA_INI DATE;
    DECLARE VDIAST INT;
    SET FECHA_FIN = CONCAT(cAno, '-12-31');
    SET FECHA_MED = CONCAT(cAno, '-03-31');
    SET FECHA_INI = CONCAT(cAno, '-01-01');
    SET VDIAST = 0;
    IF lOut = 1 THEN
        IF fecha_retiro > FECHA_MED THEN
            IF fecha_retiro > FECHA_FIN THEN
            SET VDIAST = DATEDIFF( FECHA_FIN, fecha_ingreso ) + 1;
                -- despues vemo el dFechaRet
            ELSE
            IF fecha_ingreso < FECHA_INI THEN
                SET VDIAST = DATEDIFF( fecha_retiro, FECHA_INI ) + 1;
            ELSE
                SET VDIAST = DATEDIFF( fecha_retiro, fecha_ingreso ) + 1;
            END IF;
            -- calculo de dfecharet
            END IF;
        END IF;
    ELSE
        IF fecha_retiro != '0001-01-01' THEN
            SET VDIAST = DATEDIFF( fecha_retiro, FECHA_INI ) + 1;
            -- calculo dFecRet
            IF fecha_ingreso < FECHA_FIN THEN
                IF VDIAST > 89 THEN
                    SET VDIAST = VDIAST + DATEDIFF( FECHA_FIN, fecha_ingreso );
                END IF;
            END IF;
        ELSE
            SET VDIAST = DATEDIFF( FECHA_FIN, fecha_ingreso ) + 1;
        END IF;
    END IF;
   
    SET VDIAST = GREATEST( 0, LEAST( VDIAST, 365 ) );
   
    RETURN VDIAST;
END
 


Muchas Gracias Daniel por tu predisposición y tiempo.

Saludos,

Adhemar