none
Consulta ordenadas por mes calendario RRS feed

  • Pregunta

  • Tengo una consulta realizada en SQL 2005 que me trae los totales por mes segun el año que el usuario ingrese(aca lo puse a mano) de los ingresos y egresos de un comercio, pero claro yo quiero que me traiga Enero,Febrero,Marzo,etc.
    Y la consulta me trae en este caso(que son los meses que se fueron cargando)....Abril,Julio y Junio. Cuando tendria que ser Abril,Junio y Julio....Obviamente que el order by por Month(Fecha) no me sirve. La consulta es esta:

    select

     

    case Month(Fecha) when 1 then 'Enero' when 2 then 'Febrero' when 3 then 'Marzo'when 4 then 'Abril' when 5 then 'Mayo' when 6 then 'Junio' when 7 then 'Julio' when 8 then 'Agosto'when 9 then 'Septiembre' when 10 then 'Octubre' when 11 then 'Noviembre' when 12 then 'Diciembre' end[Mes],sum(Importe)[Total Mes],M.Tipo From Movimientos M where M.Tipo in('VTA','ND','CC') and year(Fecha)=2009 group by Month(Fecha),M.Tipo
    union
    Select
    Case Month(Fecha) when 1 then 'Enero' when 2 then 'Febrero' when 3 then 'Marzo'
    when 4 then 'Abril' when 5 then 'Mayo' when 6 then 'Junio' when 7 then 'Julio' when 8 then 'Agosto'
    when 9 then 'Septiembre' when 10 then 'Octubre' when 11 then 'Noviembre' when 12 then 'Diciembre' end[Mes],sum(Importe)[Total Mes],M.Tipo From Movimientos M where M.Tipo in('PP','NC','PS','GA','PC') and year(Fecha)=2009 group by Month(Fecha),M.Tipo

    martes, 21 de julio de 2009 16:32

Respuestas

  • Para eso pones tu query actual, excepto la clausula "order by", en una tabla derivada o CTE. Luego escojes las columnas a mostrar y agregas la clausula "order by".


    USE Northwind;
    GO
    
    WITH r_set
    AS
    (
    SELECT
    	MONTH(OrderDate) AS MesNumero,
    	DATENAME([month], OrderDate) AS MesNombre,
    	COUNT(*) AS cnt
    FROM
    	dbo.Orders
    WHERE
    	CustomerID = 'ALFKI' AND OrderDate >= '19980101' AND OrderDate < '19980701'
    GROUP BY
    	MONTH(OrderDate),
    	DATENAME([month], OrderDate)
    	
    UNION ALL
    
    SELECT
    	MONTH(OrderDate) AS MesNumero,
    	DATENAME([month], OrderDate) AS MesNombre,
    	COUNT(*) AS cnt
    FROM
    	dbo.Orders
    WHERE
    	CustomerID = 'ALFKI' AND OrderDate >= '19980701' AND OrderDate < '19990101'
    GROUP BY
    	MONTH(OrderDate),
    	DATENAME([month], OrderDate)
    )
    SELECT
    	MesNombre,
    	cnt
    FROM
    	r_set
    ORDER BY
    	MesNumero;
    GO
    



    AMB
    miércoles, 22 de julio de 2009 18:27

Todas las respuestas

  • Hola.

    La función "Month(fecha)" devuelve un entero y si ordenas por ello obtendrías el resultado que buscas. Creo que estás ordenando por [Mes] y por eso te pone antes Julio que Junio. No veo porqué no te sirve el order by Month(Fecha). Añade el campo en la select para mayor claridad.



    Alberto López Grande.
    martes, 21 de julio de 2009 16:44
    Moderador
  • Gracias, pero ya habia probado eso(order by Month(Fecha)) y me tira el error:

    ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator.

    Obviamente que si pongo order by [Mes] me los trae mal o sea primero Julio y despues Junio. Lo raro es que me fijo en la tabla donde tengo estas fechas y estan bien, no se porque la consulta no me la trae tal cual como tengo en mi tabla sin ni siquiera usar el order by, ya que por defecto el orden de la tabla esta bien, se basara en los totales para ordenar o el tipo....

    martes, 21 de julio de 2009 16:58
  • Damian,

    El error te dice que esa columna debe ser parte de la lista de columnas de la clausula "select", en el caso de usar "order by" por ella y a su vez tener un "union", "union all", etc.

    Pon "Month(Fecha) as MesNumero" en cada lista.

    select
        Month(Fecha) as MesNumero,
        ...

    union all

    select
        Month(Fecha) as MesNumero,
        ...
    order by
        Month(Fecha);
    GO


    Fijate que use UNION ALL, pues a la final filtras en ambas sentencias por la columna [Tipo], pero los conjuntos son diferentes, por lo que usar el operador UNION no tiene sentido en este caso. Ademas, la operacion de filtrar valores distintos (UNION) consume mas recursos y tiempo.


    AMB
    martes, 21 de julio de 2009 18:17
  • Gracias por responder, pero no me anduvo lo que me pasas ya que me tira error:

    Msg 102, Level 15, State 1, Line 1
    Incorrect syntax near 'MesNumero'.

    Msg 102, Level 15, State 1, Line 6
    Incorrect syntax near 'MesNumero'.

    Le saque el (as) ya que tambien me tiraba error, tambien lo puse entre[] y error tambien. Recuerda que al final de mi select tengo en cada select (end[Mes]), claro esta que si quiero ordenar por [Mes] me va a traer primero Julio que Junio. Me queda alguna posibilidad. Gracias

    miércoles, 22 de julio de 2009 16:43
  • Sin ver la sentencia, es dificil dar una opinion sobre el error.

    Aqui tienes un ejemplo que simula lo que deseas hacer.


    USE Northwind;
    GO
    
    SELECT
    	MONTH(OrderDate) AS MesNumero,
    	DATENAME([month], OrderDate) AS MesNombre,
    	COUNT(*) AS cnt
    FROM
    	dbo.Orders
    WHERE
    	CustomerID = 'ALFKI' AND OrderDate >= '19980101' AND OrderDate < '19980701'
    GROUP BY
    	MONTH(OrderDate),
    	DATENAME([month], OrderDate)
    	
    UNION ALL
    
    SELECT
    	MONTH(OrderDate) AS MesNumero,
    	DATENAME([month], OrderDate) AS MesNombre,
    	COUNT(*) AS cnt
    FROM
    	dbo.Orders
    WHERE
    	CustomerID = 'ALFKI' AND OrderDate >= '19980701' AND OrderDate < '19990101'
    GROUP BY
    	MONTH(OrderDate),
    	DATENAME([month], OrderDate)
    ORDER BY
    	MONTH(OrderDate);
    GO

    AMB
    miércoles, 22 de julio de 2009 16:56
  • Bueno, ahora basandome en lo que me pasas hice unas modificaciones y ahora si me anda perfecto. Una ultima cosa y si yo quisiera desde la consulta no mostrar (MesNumero) que seria los meses en numeros, no me interesa mostrarlo ya que lo hago con el nombre de cada mes(Junio,Julio,etc...) o si o si se necesita de este para asi ordenarlos, en todo caso lo arreglo desde codigo y listo. gracias.
    miércoles, 22 de julio de 2009 17:17
  • Para eso pones tu query actual, excepto la clausula "order by", en una tabla derivada o CTE. Luego escojes las columnas a mostrar y agregas la clausula "order by".


    USE Northwind;
    GO
    
    WITH r_set
    AS
    (
    SELECT
    	MONTH(OrderDate) AS MesNumero,
    	DATENAME([month], OrderDate) AS MesNombre,
    	COUNT(*) AS cnt
    FROM
    	dbo.Orders
    WHERE
    	CustomerID = 'ALFKI' AND OrderDate >= '19980101' AND OrderDate < '19980701'
    GROUP BY
    	MONTH(OrderDate),
    	DATENAME([month], OrderDate)
    	
    UNION ALL
    
    SELECT
    	MONTH(OrderDate) AS MesNumero,
    	DATENAME([month], OrderDate) AS MesNombre,
    	COUNT(*) AS cnt
    FROM
    	dbo.Orders
    WHERE
    	CustomerID = 'ALFKI' AND OrderDate >= '19980701' AND OrderDate < '19990101'
    GROUP BY
    	MONTH(OrderDate),
    	DATENAME([month], OrderDate)
    )
    SELECT
    	MesNombre,
    	cnt
    FROM
    	r_set
    ORDER BY
    	MesNumero;
    GO
    



    AMB
    miércoles, 22 de julio de 2009 18:27
  • te esta ordenando por mes burrito pero mes en tipo varchar no como datetime
    es por eso que te lo acomoda Abril el primer lugar

    A de Abril y asi sucesivamente

    tienes que tener una fecha valida datetime
    no te explicas muy bien pero podrias usar con convert(datetime,campo)

    jueves, 23 de julio de 2009 19:20