我们可以明智地进行分区日期吗?

Posted

技术标签:

【中文标题】我们可以明智地进行分区日期吗?【英文标题】:Can we do partition date wise? 【发布时间】:2013-01-19 11:36:07 【问题描述】:

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

【问题讨论】:

请根据数据说明问题。如果您可以添加示例记录和预期输出,将会很有帮助。 【参考方案1】:

我认为您正在寻找的是这样的:

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.

【讨论】:

【参考方案2】:

当您说分区时,我很好奇您是指在窗口函数中还是在一般情况下对数据进行分组。让我在一个自我演示的示例中向您展示两种聚合数据并对其进行分区的方法:

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 子句,您必须将不执行数学运算的子句列为要处理的枢轴。所以在我的第一个选择中,我只选择了日期,然后说 sum(counts)。然后它在 1-1-12 上看到它有两个值,因此它添加了它们,并在其他所有东西上单独添加了它们。在第二种选择方法中,我对日期字段执行了一个技巧,以使其转换为该月的第一天。现在这很棒,但我可能想要一次所有这些。

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

【讨论】:

以上是关于我们可以明智地进行分区日期吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何明智地按季度分组日期?

如何在 Angular 8 或 javascript 中明智地获取当前日期每周日

如何使用带有 OAuth 令牌的 Asp.Net MVC 中的 gmail API 更快地获取日期明智的电子邮件

Apache Pig 中的 HCatalog 可以只加载特定分区吗?

BigQuery:使用 DML 原子地替换日期分区

在列出的日期范围之外流式传输到分区表 BigQuery