一、常见日期维度查询语句
--data当前日期 2020-02-02
select CONVERT(varchar(10),GETDATE(),120)
--年份
SELECT CAST(YEAR(GETDATE()) AS int)
--年季
SELECT YEAR(GETDATE())*10 + CEILING(MONTH(GETDATE())/3.0)
--年月
SELECT YEAR(GETDATE())*100 + MONTH(GETDATE())
--年周
SELECT YEAR(GETDATE())*100 + DATEPART(WK,GETDATE())
--季度
SELECT CEILING(MONTH(GETDATE())/3.0)
--月
SELECT MONTH(GETDATE())
--周
SELECT DATEPART(WK,GETDATE())
--天
SELECT DAY(GETDATE())
--年度最小日期
select dateadd(year, datediff(year, 0, GETDATE()), 0)
--年度最大日期(思路:下年的第一天减去一天)
select dateadd(year, datediff(year, 0, dateadd(year, 1, GETDATE())), -1)
--季度最小日期
SELECT DATEADD(qq, DATEDIFF(qq,0,getdate()), 0)
--季度最大日期
SELECT CONVERT(datetime,CONVERT(char(8),DATEADD(Month,DATEPART(Quarter,GETDATE())*3-Month(GETDATE()),GETDATE()),120)+CASE WHEN DATEPART(Quarter,GETDATE()) in(1,4)THEN'31'ELSE'30'END)
--月度最小日期
select dateadd(month, datediff(month, 0, GETDATE()), 0)
--月度最大日期(思路:下月的第一天减去一天)
select dateadd(month, datediff(month, 0, dateadd(month, 1, GETDATE())), -1)
--周第一天
--设置周一为每周的第一天(sql server默认周日为每周第一天)
SET DATEFIRST 1
SELECT dateadd(day,1-(datepart(weekday,GETDATE())),GETDATE())
--周最后一天(周的第一天加6)
SELECT DATEADD(day,1-(datepart(weekday,GETDATE()))+6,GETDATE())
二、建立日期维度表
CREATE TABLE [dbo].[d_time](
[id] [INT] NOT NULL,
[date] [DATETIME] NOT NULL,
[name] [NVARCHAR](11) NULL,
[year] [INT] NOT NULL,
[year_quarter] [INT] NOT NULL,
[year_month] [INT] NOT NULL,
[year_week] [INT] NOT NULL,
[quarter] [INT] NOT NULL,
[month] [INT] NOT NULL,
[week] [INT] NOT NULL,
[day] [INT] NOT NULL,
[year_begin_date] [DATE] NOT NULL,
[year_end_date] [DATE] NOT NULL,
[quarter_begin_date] [DATE] NOT NULL,
[quarter_end_date] [DATE] NOT NULL,
[month_begin_date] [DATE] NOT NULL,
[month_end_date] [DATE] NOT NULL,
[week_begin_date] [DATE] NOT NULL,
[week_end_date] [DATE] NOT NULL,
CONSTRAINT [PK_d_time] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
三、维护日期维度存储过程
CREATE ALTER PROCEDURE [dbo].[sp_insert_time] @type INT --功能类型:"0"增量,"1"全量
AS
SET NOCOUNT ON;
BEGIN
DECLARE @data DATETIME; --当前日期
DECLARE @begin_time DATETIME; --起始时间
DECLARE @end_time DATETIME; --截止日期
--设置周一为每周的第一天
SET DATEFIRST 1;
--获取当前日期(2021-11-11 00:00:00.000)
SET @data = CAST(CONVERT(VARCHAR(8), GETDATE(), 112) AS DATETIME);
--设置截止时间(当天日期向后追加一年)
SET @end_time = DATEADD(yy, 1, @data);
--判断功能类型-增量
IF @type = 0
BEGIN
--日期增量(如果表中最大日期小于明年今日)
IF(SELECT MAX(date) FROM dbo.d_time) < @end_time
BEGIN
--设置起始时间(表中存在最大日期+1天)
SET @begin_time = DATEADD(DAY,1,(SELECT MAX(date) FROM dbo.d_time));
--插入开始
WHILE @begin_time <= @end_time
BEGIN
SET @data = @begin_time;
INSERT INTO [dbo].[d_time]
(
[id],
[date],
[name],
[year],
[year_quarter],
[year_month],
[year_week],
[quarter],
[month],
[week],
[day],
[year_begin_date],
[year_end_date],
[quarter_begin_date],
[quarter_end_date],
[month_begin_date],
[month_end_date],
[week_begin_date],
[week_end_date]
)
VALUES
(cast(CONVERT(varchar(12),@data,112) AS INT )
,CONVERT(varchar(10),@data,120)
,CAST(YEAR(@data) AS VARCHAR)+'年'+RIGHT((100+ MONTH(@data)),2)+'月'+RIGHT(100+DAY(@data),2)+'日'
,CAST(YEAR(@data) AS int)
,YEAR(@data)*10 + CEILING(MONTH(@data)/3.0)
,YEAR(@data)*100 + MONTH(@data)
,YEAR(@data)*100 + DATEPART(WK,@data)
,CEILING(MONTH(@data)/3.0)
,MONTH(@data)
,DATEPART(WK,@data)
,DAY(@data)
,dateadd(year, datediff(year, 0, @data), 0)
,dateadd(year, datediff(year, 0, dateadd(year, 1, @data)), -1)
,DATEADD(qq, DATEDIFF(qq,0,getdate()), 0)
,CONVERT(datetime,CONVERT(char(8),DATEADD(Month,DATEPART(Quarter,@data)*3-Month(@data),@data),120)+CASE WHEN DATEPART(Quarter,@data) in(1,4)THEN'31'ELSE'30'END)
,dateadd(month, datediff(month, 0, @data), 0)
,dateadd(month, datediff(month, 0, dateadd(month, 1, @data)), -1)
,dateadd(day,1-(datepart(weekday,@data)),@data)
,DATEADD(day,1-(datepart(weekday,@data))+6,@data));
SET @begin_time = DATEADD(DAY, 1, @begin_time);
END;
END;
END;
----判断功能类型-全量
IF @type = 1
BEGIN
--全量前清空日期维度表
TRUNCATE TABLE [dbo].[d_time]
--先插入一条null数据
BEGIN
SET @data ='1900-01-01 00:00:00.000';
INSERT INTO [dbo].[d_time]
(
[id],
[date],
[name],
[year],
[year_quarter],
[year_month],
[year_week],
[quarter],
[month],
[week],
[day],
[year_begin_date],
[year_end_date],
[quarter_begin_date],
[quarter_end_date],
[month_begin_date],
[month_end_date],
[week_begin_date],
[week_end_date]
)
VALUES
(cast(CONVERT(varchar(12),@data,112) AS INT )
,CONVERT(varchar(10),@data,120)
,CAST(YEAR(@data) AS VARCHAR)+'年'+RIGHT((100+ MONTH(@data)),2)+'月'+RIGHT(100+DAY(@data),2)+'日'
,CAST(YEAR(@data) AS int)
,YEAR(@data)*10 + CEILING(MONTH(@data)/3.0)
,YEAR(@data)*100 + MONTH(@data)
,YEAR(@data)*100 + DATEPART(WK,@data)
,CEILING(MONTH(@data)/3.0)
,MONTH(@data)
,DATEPART(WK,@data)
,DAY(@data)
,dateadd(year, datediff(year, 0, @data), 0)
,dateadd(year, datediff(year, 0, dateadd(year, 1, @data)), -1)
,DATEADD(qq, DATEDIFF(qq,0,getdate()), 0)
,CONVERT(datetime,CONVERT(char(8),DATEADD(Month,DATEPART(Quarter,@data)*3-Month(@data),@data),120)+CASE WHEN DATEPART(Quarter,@data) in(1,4)THEN'31'ELSE'30'END)
,dateadd(month, datediff(month, 0, @data), 0)
,dateadd(month, datediff(month, 0, dateadd(month, 1, @data)), -1)
,dateadd(day,1-(datepart(weekday,@data)),@data)
,DATEADD(day,1-(datepart(weekday,@data))+6,@data));
END
--正式数据插入开始
SET @begin_time = '2018-01-01 00:00:00.000';
WHILE @begin_time < DATEADD(DAY, 1, @end_time)
BEGIN
SET @data = @begin_time;
--插入开始
INSERT INTO [dbo].[d_time]
(
[id],
[date],
[name],
[year],
[year_quarter],
[year_month],
[year_week],
[quarter],
[month],
[week],
[day],
[year_begin_date],
[year_end_date],
[quarter_begin_date],
[quarter_end_date],
[month_begin_date],
[month_end_date],
[week_begin_date],
[week_end_date]
)
VALUES
(cast(CONVERT(varchar(12),@data,112) AS INT )
,CONVERT(varchar(10),@data,120)
,CAST(YEAR(@data) AS VARCHAR)+'年'+RIGHT((100+ MONTH(@data)),2)+'月'+RIGHT(100+DAY(@data),2)+'日'
,CAST(YEAR(@data) AS int)
,YEAR(@data)*10 + CEILING(MONTH(@data)/3.0)
,YEAR(@data)*100 + MONTH(@data)
,YEAR(@data)*100 + DATEPART(WK,@data)
,CEILING(MONTH(@data)/3.0)
,MONTH(@data)
,DATEPART(WK,@data)
,DAY(@data)
,dateadd(year, datediff(year, 0, @data), 0)
,dateadd(year, datediff(year, 0, dateadd(year, 1, @data)), -1)
,DATEADD(qq, DATEDIFF(qq,0,getdate()), 0)
,CONVERT(datetime,CONVERT(char(8),DATEADD(Month,DATEPART(Quarter,@data)*3-Month(@data),@data),120)+CASE WHEN DATEPART(Quarter,@data) in(1,4)THEN'31'ELSE'30'END)
,dateadd(month, datediff(month, 0, @data), 0)
,dateadd(month, datediff(month, 0, dateadd(month, 1, @data)), -1)
,dateadd(day,1-(datepart(weekday,@data)),@data)
,DATEADD(day,1-(datepart(weekday,@data))+6,@data));
SET @begin_time = DATEADD(DAY, 1, @begin_time);
END;
END;
END;