0

我想按 YEAR-MONTH 的销售结果分组。我当前的查询结果如下:

SELECT Cast(Year(s.datekey) AS VARCHAR(4)) + '-' 
       + Cast(Month(s.datekey) AS VARCHAR(2)) AS Mjesec, 
       e.employeekey, 
       Sum(s.totalcost)                       AS SalesAmount 
FROM   factsales s 
       INNER JOIN dimstore st 
               ON s.storekey = st.storekey 
       INNER JOIN dimemployee e 
               ON e.employeekey = st.storemanager 
WHERE  s.datekey BETWEEN '2007-01-01' AND '2007-01-05' 
GROUP  BY e.employeekey, 
          Cast(Year(s.datekey) AS VARCHAR(4)) + '-' 
          + Cast(Month(s.datekey) AS VARCHAR(2)) 
ORDER  BY employeekey 

我想知道是否还有其他更好、更优雅的方法来实现相同的结果?也许,C# 中 DateTime 的更友好格式?

4

2 回答 2

1

做:

SELECT CONVERT(CHAR(7),s.DateKey,120) AS Mjesec....
FROM ....
GROUP BY CONVERT(CHAR(7),s.DateKey,120)....
ORDER BY EmployeeKey
于 2013-03-06T20:30:21.473 回答
1

通过使用日期数学来剥离时间比转换为字符串更有效。将特定的字符串格式保留到最后(或者更好的是,在 C# 中使用Format())也更有效。

;WITH c AS
(
  SELECT m = DATEADD(MONTH, DATEDIFF(MONTH, 0, s.datekey), 0),
   e.employeekey, s.totalcost
  FROM dbo.factsales AS s
  INNER JOIN dbo.dimstore AS st
  ON s.storekey = st.storekey
  INNER JOIN dimemployee AS e
  ON e.employeekey = st.storemanager
  WHERE s.datekey >= '20070101' AND s.datekey < '20070106'
),
d AS
(
  SELECT m, employeekey, SalesAmount = SUM(totalcost)
    FROM c
    GROUP BY m, employeekey
)
SELECT 
  Mjesec = CONVERT(CHAR(7), m, 120), 
  employeekey, 
  SalesAmount
FROM d
ORDER BY employeekey;

如果您可以在您的应用程序中进行格式化,那么您可以将其折叠为:

;WITH c AS
(
  SELECT m = DATEADD(MONTH, DATEDIFF(MONTH, 0, s.datekey), 0),
   e.employeekey, s.totalcost
  FROM dbo.factsales AS s
  INNER JOIN dbo.dimstore AS st
  ON s.storekey = st.storekey
  INNER JOIN dimemployee AS e
  ON e.employeekey = st.storemanager
  WHERE s.datekey >= '20070101' AND s.datekey < '20070106'
)
SELECT Mjesec = m, employeekey, SalesAmount = SUM(totalcost)
  FROM c
  GROUP BY m, employeekey
  ORDER BY employeekey;

甚至:

  SELECT Mjesec = DATEADD(MONTH, DATEDIFF(MONTH, 0, s.datekey), 0),
   e.employeekey, s.totalcost
  FROM dbo.factsales AS s
  INNER JOIN dbo.dimstore AS st
  ON s.storekey = st.storekey
  INNER JOIN dimemployee AS e
  ON e.employeekey = st.storemanager
  WHERE s.datekey >= '20070101' AND s.datekey < '20070106'
  GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, s.datekey, 0), 0), e.employeekey
  ORDER BY employeekey;
于 2013-03-06T20:35:45.570 回答