Sentencia SQL Avanzada para genera una nuevo cursos

Gracias a tu apoyo he logrado realizar una consulta que me sume mes por mes montos de una determinada tabla.

SELECT costos.ccostos,left(costos.ccuenta,3) cuentas,;
sum(iif(costos.periodo=m_ene,costos.impo,0.00)) ene,;
sum(iif(costos.periodo=m_feb,costos.impo,0.00)) feb,;
sum(iif(costos.periodo=m_nov,costos.impo,0.00)) nov,;
sum(iif(costos.periodo=m_dic,costos.impo,0.00)) dic;
from costos;
group by costos.ccostos,cuentas;
ORDER BY costos.ccostos;
into cursor resultado

El resultado de esta consulta es:

ccostos          cuentas          ene   feb ..... Dic

90121101       613                150   1500    2000

90121101       621                100   1700    2200

90121101       622                500   1400    2300

90121102       681                1000  5000  6000

Cada costos (ccostos) tiene asociada sus respectivas cuentas contables (cuentas), lo que me piden ahora es poner el nombre de cada costo (ccostos) y el nombre de cada cuenta (cuentas). Para que me muestre asi:

ccostos          nombre_costo   cuentas   nombre_cuenta       ene   feb ..... Dic

90121101       Gerencia             613        Materia Prima       150   1500    2000

90121101       Gerencia             621        Remuneraciones  100   1700    2200

90121101       Gerencia             622        Depreciacion         500   1400    2300

90121102       Administracion    681        Maquinaria             1000  5000  6000

La tabla con que se relaciona los costos es centros y el campo común seria ccostos, la tabla con que se relaciona las cuentas contables seria cuentas y el campo común seria ccuenta. Estuve haciendo esto:

SELECT costos.ccostos, centro_costos.desc1, costos.ccuenta, cuentas_contables.desc2,;
costos.ene,costos.feb,costos.mar,costos.dic;
FROM costos;
INNER JOIN centros ON centros.ccostos=costos.ccostos;
inner JOIN cuentas ON LEFT(cuentas.ccuenta,3)=costos.ccuenta;
order BY costos.ccostos;
into CURSOR resultado

Me muestra:

ccostos          nombre_costo   cuentas   nombre_cuenta       ene   feb ..... Dic

90121101       Gerencia             613        Materia Prima       150   100    200

90121101       Gerencia             613        Remuneraciones  150   100    200

90121101       Gerencia             613        Depreciacion         150   100    200

90121101       Gerencia             613        Maq y equipo         150   100    200

Se repiten las cuentas.

Al final lo que quiero hacer es un reporte en donde me muestre la sumatoria de las cuentas por cada costo, para luego exportarlo a excel.

Costo: Gerencia          

Cuentas:                

                          Ene      Feb   Mar

         613           150       

         621           100

         622           500

         681          1000

Total Gerencia: 1,750

1 respuesta

Respuesta

Entiendo que usas SQL Server; entiendo que la estructura es como sigue:

Tabla relacional "costos":

Campo "periodo"
     Campo "impo"
     Campo "ccuenta"
     Campo "ccostos"

Tabla "centro_costos"
     Campo "ccostos"
     Campo "desc1"

Tabla "cuentas_contables"
     Campo "ccuenta"
     Campo "desc2"

No entiendo porqué haces referencia a centros cuando se supone que es centro_costos... ¿hay más tablas intermedias?

Suponiendo que todo sea de esta forma, entonces el problema está en los Joins. Podrías probar a realizar los Joins de forma lógica y no de forma natural que es como los tienes ahora:

SELECT costos.ccostos, centro_costos.desc1, costos.ccuenta, cuentas_contables.desc2
FROM costos,centro_costos,cuentas_contables
WHERE costos.ccuenta = cuentas_contables.ccuenta
AND costos.ccostos = centro_costos.ccostos

Adapta esta sentencia SQL a Transact y mira el resultado, luego realiza las agrupaciones para el sumatorio.

También detecto los siguientes errores en la consulta original:

SELECT costos.ccostos, centro_costos.desc1, costos.ccuenta, cuentas_contables.desc2,;

costos.ene,costos.feb,costos.mar,costos.dic;
FROM costos;
INNER JOIN centros ON costos.ccostos = centros.ccostos; -- ERROR: las tablas estaban intercambiadas (comparala con tu original)
inner JOIN cuentas ON LEFT(cuentas.ccuenta,3)=costos.ccuenta; -- ATENCION: ON LEFT puede generarte duplicados ¿tienes nulos? Revisa este Join porque parece que está mal construido
order BY costos.ccostos;
into CURSOR resultado

Gracias por contestar: Te quería decir que las sentencias SQL la estoy usando en Vfox8.

No entiendo porqué haces referencia a centros cuando se supone que es centro_costos... ¿hay más tablas intermedias?

La tabla es centro_costos seguro fue un error de tipeo.

INNER JOIN centros ON costos.ccostos = centros_costos.ccostos; -- ERROR: las tablas estaban intercambiadas (comparala con tu original)

A que te refieres con decir que las tablas están intercambiadas

inner JOIN cuentas ON LEFT(cuentas_contables.ccuenta,3)=costos.ccuenta; -- ATENCION: ON LEFT puede generarte duplicados ¿tienes nulos? Revisa este Join porque parece que está mal construido

No tengo nulos, lo que pasa es que la cuentas contables deber ser a tres digitos ya que existen a 3, 4,7 y 9.  en la tabla cuentas_contables. Por eso estoy usando left solo para comparar los primeros 3 dígitos con la tabla cuentas_contables.

  • La tabla es centro_costos seguro fue un error de tipeo.
    • OK
  • A que te refieres con decir que las tablas están intercambiadas
    • Como lo tenías era:
    • FROM costos; INNER JOIN centros ON centros.ccostos = costos. Ccostos;
    • Y el formalismo indica que la tabla del from debe estar a la izquierda del término de igualación de la cláusula ON, quedando así (marcado en negrita):
    • FROM costos; INNER JOIN centros ON costos.ccostos = centros. Ccostos;
    • Parece una tontería, pero algunos gestores de BD no funcionan por estas tonterías.
  • No tengo nulos, lo que pasa es que la cuentas contables deber ser a tres digitos ya que existen a 3, 4,7 y 9. en la tabla cuentas_contables. Por eso estoy usando left solo para comparar los primeros 3 dígitos con la tabla cuentas_contables.
    • Pues ya tenemos una posibilidad de repeticiones, ya que pueden haber varias cuentas que coincidan con esa búsqueda, por ejemplo:
      • Cuenta: 123
      • Cuenta: 9873123
      • Cuenta: 1237
  • Otra cosa, es que en el segundo Join, usas un INNER (¿por rendimiento?):
    • inner JOIN cuentas ON LEFT(cuentas_contables.ccuenta,3)=costos. Ccuenta;
  • Según la sintáxis de Vfox, debería ser así:
    • JOIN cuentas ON LEFT(cuentas_contables.ccuenta,3)=costos.ccuenta;
  • ¿Probaste la consulta con joins lógicos?

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas