none
Incluir más columnas a funciones de agregado RRS feed

  • Pregunta

  • Hola que tal buen día.

    Estoy haciendo una consulta que incluye múltiples inner joins y pivot; pero me hacen falta 3 campos que provienen de distintas tablas que mediante otros inners joins lo lograría; sin embargo, al intentar hacer el inner join e incluir el campo que requiero, me pide que incluya dicho campo en función de agregado y en group by; pero estos campos no tienen sentido incluirlos en tales clausulas; ya que son complemento del código de producto. anexo consulta que hasta el momento he construido. Espero me puedan apoyar y de antemano les agradezco su valioso apoyo. Gracias

    Saludos

    select 
    CCODIGOPRODUCTO,
    CNOMBREPRODUCTO,
    Case when January is not null then January else 0 end as Enero,
    Case when February is not null then February else 0 end as Febrero,
    Case when March is not null then March else 0 end as Marzo,
    Case when April is not null then April else 0 end as Abril,
    Case when May is not null then May else 0 end as Mayo,
    Case when June is not null then June else 0 end as Junio,
    Case when July is not null then July else 0 end as Julio,
    Case when August is not null then August else 0 end as Agosto,
    Case when September is not null then September else 0 end as Septiembre,
    Case when October is not null then October else 0 end as Octubre,
    Case when November is not null then  November else 0 end as Noviembre,
    Case when December is not null then December else 0 end as Diciembre
    
    from
    
    (SELECT P.CCODIGOPRODUCTO, P.CNOMBREPRODUCTO, sum(CUNIDADES) as Total, DATENAME(month,M.CFECHA) AS FECHA 
    FROM admMovimientos M INNER JOIN admProductos P ON M.CIDPRODUCTO=P.CIDPRODUCTO
    INNER JOIN admDocumentos D ON M.CIDDOCUMENTO=D.CIDDOCUMENTO
    WHERE (M.CIDDOCUMENTODE=4 or M.CIDDOCUMENTODE=33 or M.CIDDOCUMENTODE=3) AND (D.CCANCELADO=0) 
    AND M.CFECHA BETWEEN '2018-01-01' AND '2018-12-31'
    group by p.CCODIGOPRODUCTO, p.CNOMBREPRODUCTO,DATENAME(month,M.CFECHA)
    )t
    pivot (
    sum(t.Total)
    for FECHA in (January, February, March, April, May, June, July, August, September, October, November, December)
    ) as PVT

    Gracias

    martes, 22 de mayo de 2018 0:57

Respuestas

  • Hola yorch_

    En la clausula where del origen de dato, estas excluyendo los registros de productos, que tengan un movimiento cuyo CIDDOCUMENTO IS NULL.... Siendo posible, where ( todo lo que dices ) OR M.CIDDOCUMENTO IS NULL

    WHERE (M.CIDDOCUMENTODE=4 or M.CIDDOCUMENTODE=33 or M.CIDDOCUMENTODE=3) AND (D.CCANCELADO=0) AND M.CFECHA BETWEEN CONCAT(YEAR(GETDATE()),'','-01','-01') AND CONCAT(YEAR(GETDATE()),'','-12','-31')

    En cuanto al desempeño, porque no le das la vuelta a la consulta. y sacas todos tus movimientos con relaciones inner join, y luego le haces a todo tu select * FROM ( SELECT CODIGO PRODUCTO, .... AS PVT) AS RESULTADO LEFT JOIN PRODUCTOS P ON RESULTADO.CODIGOPRODUCTO = P.CODIGOPRODUCTO

    El desempeño de los left join cuando la cantidad de datos a tratar es grande, digamos que es complicado, y más si encima lo sometes a un pivot.

    Un saludo

    • Marcado como respuesta Jorge Chuc miércoles, 23 de mayo de 2018 13:00
    martes, 22 de mayo de 2018 4:36
  • Prueba a utilizar el comando UNION. Une los datos resultantes de dos querys que comparten los mismos campos.

    	SELECT a.eMail FROM tbAgentes AS a WHERE LEN(a.eMail) > 0 AND a.idAgente = @Agente
    	UNION ALL 
    	SELECT c.eMail FROM tbContactosAgente AS c WHERE (LEN(c.eMail)) > 0 AND c.idAgente = @Agente
    

    En este caso necesitaba obtener los eMail de los agentes, pero también, los eMail de los Contactos.

    espero te sirva.

    un saludo.

    • Marcado como respuesta Jorge Chuc miércoles, 23 de mayo de 2018 13:00
    martes, 22 de mayo de 2018 6:12

Todas las respuestas

  • Hola, podrías poner la estructura de las tablas algo de data y los campos que deseas agregar?

    Por otro lado te mueve el resultado de la consulta si agregas esos campos en el group by


    Votar es agradecer.
    Saludos.
    Lima-Perú

    martes, 22 de mayo de 2018 1:13
  • Incluí las columnas y ya me da el resultado; ahora a lo que me enfrento es a las filas de productos que me muestra. En mi consulta me muestra solo aquellos productos que tienen ventas, pero lo que yo requiero es que me muestra TODOS los productos sin importar si tienen o no existencia; inclusive ya estuve haciendo muchas pruebas con el left join de modo que me muestre todos los de la izquierda que es la tabla de productos pero sigue el resultado igual. También incluí en el where que me muestre los que tienen el idproducto=null pero tampoco cambia el resultado; no se que tanto me esté afectando los where o el pivot. De que otra manera puedo optimizar mi código de modo que me muestre todos los productos? Gracias por su apoyo

    Saludos

    Asi está mi código:

    select 
    CCODIGOPRODUCTO,
    CNOMBREPRODUCTO,
    CVALORCLASIFICACION,
    UBICACION,
    Case when January is not null then January else 0 end as Enero,
    Case when February is not null then February else 0 end as Febrero,
    Case when March is not null then March else 0 end as Marzo,
    Case when April is not null then April else 0 end as Abril,
    Case when May is not null then May else 0 end as Mayo,
    Case when June is not null then June else 0 end as Junio,
    Case when July is not null then July else 0 end as Julio,
    Case when August is not null then August else 0 end as Agosto,
    Case when September is not null then September else 0 end as Septiembre,
    Case when October is not null then October else 0 end as Octubre,
    Case when November is not null then  November else 0 end as Noviembre,
    Case when December is not null then December else 0 end as Diciembre
    
    from
    
    (SELECT P.CCODIGOPRODUCTO, P.CNOMBREPRODUCTO, sum(CUNIDADES) as Total, DATENAME(month,M.CFECHA) AS FECHA, C.CVALORCLASIFICACION, 
    CONCAT(CZONA, CPASILLO, CANAQUEL, CREPISA) AS UBICACION
    FROM admProductos P left JOIN admMovimientos M  ON P.CIDPRODUCTO=M.CIDPRODUCTO
    LEFT JOIN admClasificacionesValores C ON P.CIDVALORCLASIFICACION1=C.CIDVALORCLASIFICACION
    LEFT JOIN admMaximosMinimos MM ON P.CIDPRODUCTO=MM.CIDPRODUCTO
    LEFT JOIN admDocumentos D ON M.CIDDOCUMENTO=D.CIDDOCUMENTO
    WHERE (M.CIDDOCUMENTODE=4 or M.CIDDOCUMENTODE=33 or M.CIDDOCUMENTODE=3) AND (D.CCANCELADO=0) 
    AND M.CFECHA BETWEEN CONCAT(YEAR(GETDATE()),'','-01','-01') AND CONCAT(YEAR(GETDATE()),'','-12','-31')
    group by p.CCODIGOPRODUCTO, p.CNOMBREPRODUCTO,DATENAME(month,M.CFECHA),C.CVALORCLASIFICACION,CZONA,CPASILLO,CANAQUEL,CREPISA
    )t
    pivot (
    sum(t.Total)
    for FECHA in (January, February, March, April, May, June, July, August, September, October, November, December)
    ) as PVT

    martes, 22 de mayo de 2018 3:53
  • Hola yorch_

    En la clausula where del origen de dato, estas excluyendo los registros de productos, que tengan un movimiento cuyo CIDDOCUMENTO IS NULL.... Siendo posible, where ( todo lo que dices ) OR M.CIDDOCUMENTO IS NULL

    WHERE (M.CIDDOCUMENTODE=4 or M.CIDDOCUMENTODE=33 or M.CIDDOCUMENTODE=3) AND (D.CCANCELADO=0) AND M.CFECHA BETWEEN CONCAT(YEAR(GETDATE()),'','-01','-01') AND CONCAT(YEAR(GETDATE()),'','-12','-31')

    En cuanto al desempeño, porque no le das la vuelta a la consulta. y sacas todos tus movimientos con relaciones inner join, y luego le haces a todo tu select * FROM ( SELECT CODIGO PRODUCTO, .... AS PVT) AS RESULTADO LEFT JOIN PRODUCTOS P ON RESULTADO.CODIGOPRODUCTO = P.CODIGOPRODUCTO

    El desempeño de los left join cuando la cantidad de datos a tratar es grande, digamos que es complicado, y más si encima lo sometes a un pivot.

    Un saludo

    • Marcado como respuesta Jorge Chuc miércoles, 23 de mayo de 2018 13:00
    martes, 22 de mayo de 2018 4:36
  • Prueba a utilizar el comando UNION. Une los datos resultantes de dos querys que comparten los mismos campos.

    	SELECT a.eMail FROM tbAgentes AS a WHERE LEN(a.eMail) > 0 AND a.idAgente = @Agente
    	UNION ALL 
    	SELECT c.eMail FROM tbContactosAgente AS c WHERE (LEN(c.eMail)) > 0 AND c.idAgente = @Agente
    

    En este caso necesitaba obtener los eMail de los agentes, pero también, los eMail de los Contactos.

    espero te sirva.

    un saludo.

    • Marcado como respuesta Jorge Chuc miércoles, 23 de mayo de 2018 13:00
    martes, 22 de mayo de 2018 6:12
  • He resuelto mi problema cambiando un poco la estructura de mi consulta. en vez de hacer inner con la tabla con todos los datos; primero hago el filtro con los datos que requiero. Esto para no restringir el resultado en el where. Gracias por su valioso apoyo.

    select 
    CCODIGOPRODUCTO,
    CNOMBREPRODUCTO,
    CVALORCLASIFICACION,
    UBICACION,
    Case when January is not null then January else 0 end as Enero,
    Case when February is not null then February else 0 end as Febrero,
    Case when March is not null then March else 0 end as Marzo,
    Case when April is not null then April else 0 end as Abril,
    Case when May is not null then May else 0 end as Mayo,
    Case when June is not null then June else 0 end as Junio,
    Case when July is not null then July else 0 end as Julio,
    Case when August is not null then August else 0 end as Agosto,
    Case when September is not null then September else 0 end as Septiembre,
    Case when October is not null then October else 0 end as Octubre,
    Case when November is not null then  November else 0 end as Noviembre,
    Case when December is not null then December else 0 end as Diciembre
    
    from
    
    (
    SELECT P.CCODIGOPRODUCTO, P.CNOMBREPRODUCTO, C.CVALORCLASIFICACION, CONCAT(CZONA, CPASILLO, CANAQUEL, CREPISA) AS UBICACION,
    sum(M.CUNIDADES) as TOTAL, DATENAME(month,M.CFECHA) AS FECHA
    FROM admProductos P LEFT JOIN admClasificacionesValores C ON P.CIDVALORCLASIFICACION1=C.CIDVALORCLASIFICACION
    LEFT JOIN admMaximosMinimos MM ON P.CIDPRODUCTO=MM.CIDPRODUCTO
    LEFT JOIN (SELECT CIDDOCUMENTO,CIDPRODUCTO,CUNIDADES,CFECHA FROM admMovimientos WHERE CIDDOCUMENTODE=4 or CIDDOCUMENTODE=33 or CIDDOCUMENTODE=3 ) M  ON P.CIDPRODUCTO=M.CIDPRODUCTO 
    LEFT JOIN (SELECT CIDDOCUMENTO FROM admDocumentos WHERE CCANCELADO=0) D ON M.CIDDOCUMENTO=D.CIDDOCUMENTO
    --WHERE P.CCODIGOPRODUCTO<>NULL
    --WHERE (M.CIDDOCUMENTODE=4 or M.CIDDOCUMENTODE=33 or M.CIDDOCUMENTODE=3) AND (D.CCANCELADO=0)
    group by p.CCODIGOPRODUCTO, p.CNOMBREPRODUCTO,C.CVALORCLASIFICACION,CZONA,CPASILLO,CANAQUEL,CREPISA,DATENAME(month,M.CFECHA)
    )t
    pivot (
    sum(t.Total)
    for FECHA in (January, February, March, April, May, June, July, August, September, October, November, December)
    ) as PVT

    miércoles, 23 de mayo de 2018 12:59