简体   繁体   中英

I need data in the order of month in year from March april may and then june

SELECT     MonthName, SUM(ExpenseClaimCount) AS Expr1, 'EXPENSE-CLAIM' AS ROW_TYPE
FROM         (SELECT     b.OrganisationID, a.ExpenseClaimCount, c.MonthName
                       FROM          Fact.MonthlyFactOrgMap AS a INNER JOIN
                                              Dim.DimOrganisation AS b ON a.DimOrganisationKey = b.DimOrganisationKey INNER JOIN
                                              Dim.DimDate AS c ON a.DateKey = c.DateKey
                       WHERE      (c.CalendarYear = 2014) AND (c.FullDate BETWEEN b.RowStartDate AND b.RowEndDate) AND (c.MonthName IN ('March', 'April', 'May', 'June')) AND 
                                              (a.ExpenseClaimCount > 0)) AS q
GROUP BY MonthName
UNION
SELECT     MonthName, SUM(FixedAssetCount) AS Expr1, 'FIXED ASSET' AS ROW_TYPE
FROM         (SELECT     b.OrganisationID, a.FixedAssetCount, c.MonthName
                       FROM          Fact.MonthlyFactOrgMap AS a INNER JOIN
                                              Dim.DimOrganisation AS b ON a.DimOrganisationKey = b.DimOrganisationKey INNER JOIN
                                              Dim.DimDate AS c ON a.DateKey = c.DateKey
                       WHERE      (c.CalendarYear = 2014) AND (c.FullDate BETWEEN b.RowStartDate AND b.RowEndDate) AND (c.MonthName IN ('March', 'April', 'May', 'June')) AND 
                                              (a.FixedAssetCount > 0)) AS q_2

GROUP BY MonthName

This is the query that I have ...all the suggestions below worked but not with union

试试这个ORDER BY

ORDER BY CHARINDEX(LEFT(MonthName,3),'AprMayJunJulAugSepOctNovDecJanFebMar')

If you need data in a particular order, you should add a group by clause. In this case, group by monthname will produce the alphabetical order you do not want. So try this instead:

order by (case when MonthName = 'March' then 3
               when MonthName = 'April' then 4
               when MonthName = 'May' then 5
               when MonthName = 'June' then 6
          end)

Depending on the database there are simpler ways of expressing this idea.

EDIT:

Perhaps a better approach is to keep the minimum date for each month and use that for ordering. Also, you don't need the subquery:

  SELECT c.MonthName, SUM(a.ExpenseClaimCount) as expr1, 'EXPENSE-CLAIM' AS ROW_TYPE
   FROM Fact.MonthlyFactOrgMap AS a
   INNER JOIN Dim.DimOrganisation AS b ON a.DimOrganisationKey = b.DimOrganisationKey
   INNER JOIN Dim.DimDate AS c ON a.DateKey = c.DateKey
   WHERE (c.CalendarYear = 2014)
     AND (c.FullDate BETWEEN b.RowStartDate AND b.RowEndDate)
     AND (c.MonthName IN ('March', 'April', 'May', 'June'))
     AND (a.ExpenseClaimCount > 0)) AS q
   GROUP BY MonthName
   ORDER BY MIN(c.FullDate);

You will want to convert the string to a number, which can be done by converting it to a DATE format and then getting the MM datepart from it.

-- the day and year don't matter because we only care about month
DATEPART(MM, CONVERT(DATE, [MonthName] + '01, 2000', 110))

So your query would look something like this

SELECT 
    DATEPART(MM, CONVERT(DATE, 'May' + '01, 2000', 110))
    MonthName,
       SUM(ExpenseClaimCount) AS Expr1,
       'EXPENSE-CLAIM' AS ROW_TYPE
FROM
  (SELECT b.OrganisationID,
          a.ExpenseClaimCount,
          c.MonthName
   FROM Fact.MonthlyFactOrgMap AS a
   INNER JOIN Dim.DimOrganisation AS b ON a.DimOrganisationKey = b.DimOrganisationKey
   INNER JOIN Dim.DimDate AS c ON a.DateKey = c.DateKey
   WHERE (c.CalendarYear = 2014)
     AND (c.FullDate BETWEEN b.RowStartDate AND b.RowEndDate)
     AND (c.MonthName IN ('March',
                          'April',
                          'May',
                          'June'))
     AND (a.ExpenseClaimCount > 0)) AS q
GROUP BY DATEPART(MM, CONVERT(DATE, 'May' + '01, 2000', 110)), MonthName
ORDER BY DATEPART(MM, CONVERT(DATE, 'May' + '01, 2000', 110))

Assuming monthname matches the month in fulldate :

SELECT MonthName,
       SUM(ExpenseClaimCount) AS Expr1,
       'EXPENSE-CLAIM' AS ROW_TYPE
FROM
(
    SELECT b.OrganisationID,
    a.ExpenseClaimCount,
    c.MonthName,
    c.FullDate
    FROM Fact.MonthlyFactOrgMap AS a
    INNER JOIN Dim.DimOrganisation AS b ON a.DimOrganisationKey = b.DimOrganisationKey
    INNER JOIN Dim.DimDate AS c ON a.DateKey = c.DateKey
    WHERE (c.CalendarYear = 2014)
    AND (c.FullDate BETWEEN b.RowStartDate AND b.RowEndDate)
    AND (c.MonthName IN ('March', 'April', 'May', 'June'))
    AND (a.ExpenseClaimCount > 0)
) AS q
GROUP BY MonthName
order by (DATEPART(month,FullDate) + 8) % 12 

Otherwise you'll need to join a table giving the date order to your table to get a numeric version of the month name; example here using a common table expression to generate a virtual table for this purpose:

;with cteMonths (name, monthDate) as
(
    select datename(month,'1900-01-01'), cast('1900-01-01' as date)

    union all

    select DATENAME(month,dateadd(month,1,monthdate))
    ,dateadd(month,1,monthdate)
    from ctemonths 
    where monthDate < '1900-12-01'
)
SELECT MonthName,
       SUM(ExpenseClaimCount) AS Expr1,
       'EXPENSE-CLAIM' AS ROW_TYPE
FROM
(
    SELECT b.OrganisationID,
    a.ExpenseClaimCount,
    c.MonthName
    FROM Fact.MonthlyFactOrgMap AS a
    INNER JOIN Dim.DimOrganisation AS b ON a.DimOrganisationKey = b.DimOrganisationKey
    INNER JOIN Dim.DimDate AS c ON a.DateKey = c.DateKey
    WHERE (c.CalendarYear = 2014)
    AND (c.FullDate BETWEEN b.RowStartDate AND b.RowEndDate)
    AND (c.MonthName IN ('March', 'April', 'May', 'June'))
    AND (a.ExpenseClaimCount > 0)
) AS q
inner join
(
    select name
    , (DATEPART(month,monthdate) + 8) % 12 displayOrder
    from cteMonths 
) x
on x.name = q.monthname
GROUP BY MonthName
order by x.displayOrder

Explanation

  • (DATEPART(month,fulldate) + 8) % 12 is the important bit of this code.

  • datepart extracts the numeric value of the month (eg 2014-07-03 -> 7)

  • % 12 means is the mathematic modulus function; ie what's the remainder after I divide this number by 12; so 7 % 12 is 7, 12 % 12 is 0, and 14 % 12 is 2.

  • +8 provides an offset to make April the first month; since 4 (april) + 8 = 12, and 12 % 12 = 0, making this the first in the sequence.

  • I did +8 instead of -4 as a workaround for a SQL nuance; in SQL -1 % 12 is -1; in most other systems it would be 11. By adding 8 we avoid the need to deal with negative numbers, so avoid this issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM