FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Consulta en MySQL
Posts: 1710
Joined: Tue Oct 28, 2008 06:26 PM
Consulta en MySQL
Posted: Thu Oct 02, 2014 02:34 PM
Amigos como se hace consulta concatenada

Aquí el código, funciona pero muy lento
Code (fw): Select all Collapse
        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
Saludos,



Adhemar C.
Posts: 601
Joined: Wed Jul 04, 2007 03:51 PM
Re: Consulta en MySQL
Posted: Thu Oct 02, 2014 04:35 PM
Hola,
Yo probaría traerme todo en un mismo Query usando "UNION"

Code (fw): Select all Collapse
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 (fw): Select all Collapse
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,
Ojeda Esteban Eduardo.

Buenos Aires - Argentina.

FWH - PellesC - DBF/CDX - ADS - Gloriosos .Bat - MySql - C# .net - FastReport

Skype: jreduojeda
Posts: 1710
Joined: Tue Oct 28, 2008 06:26 PM
Re: Consulta en MySQL
Posted: Thu Oct 02, 2014 04:44 PM

Gracias Esteban

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

Saludos,

Adhemar

Saludos,



Adhemar C.
Posts: 601
Joined: Wed Jul 04, 2007 03:51 PM
Re: Consulta en MySQL
Posted: Thu Oct 02, 2014 04:50 PM

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...

Ojeda Esteban Eduardo.

Buenos Aires - Argentina.

FWH - PellesC - DBF/CDX - ADS - Gloriosos .Bat - MySql - C# .net - FastReport

Skype: jreduojeda
Posts: 1710
Joined: Tue Oct 28, 2008 06:26 PM
Re: Consulta en MySQL
Posted: Thu Oct 02, 2014 05:05 PM

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

Saludos,



Adhemar C.
Posts: 2365
Joined: Wed Nov 02, 2005 11:46 PM
Re: Consulta en MySQL
Posted: Fri Oct 03, 2014 11:34 AM

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

Posts: 601
Joined: Wed Jul 04, 2007 03:51 PM
Re: Consulta en MySQL
Posted: Fri Oct 03, 2014 11:52 AM

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,

Ojeda Esteban Eduardo.

Buenos Aires - Argentina.

FWH - PellesC - DBF/CDX - ADS - Gloriosos .Bat - MySql - C# .net - FastReport

Skype: jreduojeda
Posts: 2064
Joined: Fri Jan 06, 2006 09:28 PM
Re: Consulta en MySQL
Posted: Fri Oct 03, 2014 08:24 PM
Yo lo hago asi sin UNIONES y me trabaja rapidos...saludos... :-)

Code (fw): Select all Collapse
         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 )
Dios no está muerto...



Gracias a mi Dios ante todo!
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Consulta en MySQL
Posted: Mon Oct 06, 2014 01:01 PM
Eduardo hacer eso en SQL es una barbaridad.
Las uniones se hacen para tablas diferentes con estructuras similares.
Esto que tú pones:
Code (fw): Select all Collapse
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 (fw): Select all Collapse
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...
:-)
______________________________________________________________________________

Sevilla - Andalucía
Posts: 1380
Joined: Fri Oct 14, 2005 01:28 PM
Re: Consulta en MySQL
Posted: Mon Oct 06, 2014 01:22 PM
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
Resistencia - "Ciudad de las Esculturas"

Chaco - Argentina
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Consulta en MySQL
Posted: Mon Oct 06, 2014 03:44 PM

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...

______________________________________________________________________________

Sevilla - Andalucía
Posts: 1380
Joined: Fri Oct 14, 2005 01:28 PM
Re: Consulta en MySQL
Posted: Mon Oct 06, 2014 04:22 PM

gracias Manu!

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

Resistencia - "Ciudad de las Esculturas"

Chaco - Argentina
Posts: 1710
Joined: Tue Oct 28, 2008 06:26 PM
Re: Consulta en MySQL
Posted: Mon Oct 06, 2014 05:16 PM
Con la ayuda de Daniel Garcia
He logrado hacer la consulta, un poco compleja:

Code (fw): Select all Collapse
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 (fw): Select all Collapse
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
Saludos,



Adhemar C.

Continue the discussion