我们可以明智地划分日期吗?

时间:2013-01-19 11:36:08

标签: sql sql-server-2008

我是分区概念的新手。我知道水平分区但是我们可以分区日期吗? 在我的项目中,我希望每当我们进入新的一年时,都应该创建分区。任何人都可以解释如何做到这一点?我正在研究ERP sw,它有过去一年的数据,我需要按年分配。(例如APR-2011到MAR-2012是一年)

2 个答案:

答案 0 :(得分:0)

我认为你要找的是这样的:

DECLARE @referenceDate datetime = '3/1/2011'

SELECT
  [sub].[Period] + 1 AS [PeriodNr],
  YEAR(DATEADD(YEAR, [sub].[Period], @referenceDate)) AS [PeriodStartedIn],
  COUNT(*) AS [NumberOfRecords],
  SUM([sub].[Value]) AS [TotalValue]
FROM
(
  SELECT
    *,
    FLOOR(DATEDIFF(MONTH, @referenceDate, [timestamp]) / 12.0) AS [Period]
  FROM [erp]
  WHERE [timestamp] >= @referenceDate
) AS [sub]
GROUP BY [sub].[Period]
ORDER BY [sub].[Period] ASC

The fiddle is found here

答案 1 :(得分:0)

当你说分区时我很好奇,如果你的意思是在窗口函数或只是分组数据。让我向您展示两种聚合数据的方法,并在自我演示示例中对其进行分区:

declare @Orders table( id int identity, dt date, counts int)

insert into @Orders values ('1-1-12', 2),('1-1-12', 3),('1-18-12', 1),('2-11-12', 5),('3-1-12', 2),('6-1-12', 8),('10-1-12', 2),('1-13-13', 8)


-- To do days I need to do a group by
select 
    dt as DayDate
,   SUM(counts) as sums
from @Orders
group by dt

-- To do months I need to group differently
select 
    DATEADD(month, datediff(month, 0, dt), 0) as MonthDate
-- above is a grouping trick basically stating count from 1/1/1900 the number of months of difference from my date field.  
--This will always yield the current first day of the month of a date field
,   SUM(counts) as sums
from @Orders
group by DATEADD(month, datediff(month, 0, dt), 0)

-- well that is great but what if I want to group different ways all at once?


-- why windowed functions rock:
select
    dt
,   counts
,   SUM(counts) over(partition by DATEADD(year, datediff(year, 0, dt), 0)) as YearPartitioning
,   SUM(counts) over(partition by DATEADD(month, datediff(month, 0, dt), 0)) as MonthPartitioning
-- expression above will work for year, month, day, minute, etc.  You just need to add it to both the dateadd and datediff functions
,   SUM(counts) over(partition by dt) as DayPartitioning
from @Orders

关于分组的重要概念是传统的group by子句,你必须列出那些不执行数学运算的作为工作的支点。所以在我的第一个选择中我只选择了日期然后说总和(计数)。然后它在1-1-12看到它有两个值,所以它添加了它们,并且在其他所有内容中单独添加它们。在第二个选择方法上,我在日期字段上执行一个技巧,使其转换为该月的第一天。现在这很好,但我可能会立刻想要所有这些。

窗口函数进行内联分组,这意味着它们不需要分组子句,因为over()部分正在执行此操作。但是,它可能会重复这些值,因为您不限制数据集。这意味着如果你看第三列的第三列选择'YearPartitioning',它会重复数字23七次。为什么?好吧,因为你从来没有告诉语句在函数之外进行任何分组,所以它显示每一行。只要表达式为真,所有值的年份相同,就会出现数字23。从窗口表达式中选择时,请记住这一点。