我需要从4月3月到6月的月份顺序的数据

时间:2014-07-03 21:52:23

标签: sql sql-server sql-server-2012

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

这是我的查询...以下所有建议都有效,但没有使用union

4 个答案:

答案 0 :(得分:1)

试试这个ORDER BY

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

答案 1 :(得分:0)

如果您需要特定订单的数据,则应添加group by子句。在这种情况下,group by monthname将生成您不想要的字母顺序。所以试试这个:

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

根据数据库,有更简单的方式来表达这个想法。

编辑:

或许更好的方法是保持每个月的最短日期并将其用于订购。此外,您不需要子查询:

  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);

答案 2 :(得分:0)

您需要将字符串转换为数字,这可以通过将其转换为DATE格式然后从中获取MM datepart来完成。

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

所以你的查询看起来像这样

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

答案 3 :(得分:0)

假设monthnamefulldate中的月份匹配:

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 

否则,您需要加入一个表格,为您的表格提供日期顺序,以获取月份名称的数字版本;例如,使用公用表表达式为此目的生成虚拟表:

;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

<强>解释

  • (DATEPART(month,fulldate) + 8) % 12是此代码的重要部分。

  • datepart提取月份的数值(例如2014-07-03 - &gt; 7)

  • % 12表示数学模数函数;即把这个数除以12之后剩下的是什么;因此7 % 12为7,12 % 12为0,14 % 12为2。

  • +8提供了抵消,使4月成为第一个月;从4(4月)+ 8 = 12,12%12 = 0,这是序列中的第一个。

  • 我做了+8而不是-4作为SQL细微差别的解决方法;在SQL -1 % 12中是-1;在大多数其他系统中它将是11.通过添加8,我们避免需要处理负数,因此避免这个问题。