如何为数据仓库的尼泊尔国家/地区创建和填充日期时间维度表 [英] how to create and populate Date Time dimension table for Nepal country for data warehouse

查看:113
本文介绍了如何为数据仓库的尼泊尔国家/地区创建和填充日期时间维度表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





如何创建和填充尼泊尔国家数据仓库的日期时间。

我想要20以下文件中的数据根据​​印地语日历(对于尼泊尔国家)



 创建  TABLE  [dbo]。[dim_time](
[YearLabel] [ char ]( 10 NULL
[QtrLabel] [ nvarchar ]( 20 NULL
[MonthLabel] [< span class =code-keyword> nvarchar ]( 20 NULL
[WeekLabel] [ nvarchar ]( 20 NULL
[DayLabel] [ nvarchar ]( 20 NULL
[MonthSort] [ int ] NULL
[WeekSort] [ int ] NULL
[DaySort] [ int ] NULL
[DayofWeek] [ nvarchar ]( 20 NULL
[月] [ datetime ] NULL
[TimeDate] [ datetime ] NULL
[TimeKey] [ int ] NOT NULL
[FiscalMonth] [ nchar ]( 20 NULL
[FiscalQtr] [ nchar ]( 20 NULL
[FiscalYear] [ nchar ]( 20 NULL
[WeekPeriod] [ int ] NULL
[DayNumber] [ int ] NULL
[workday_be] [ tinyint ] NULL
[workday_nl] [ tinyint ] NULL
CONSTRAINT [PK_DimTime] PRIMARY KEY CLUSTERED

[TimeKey] < span class =code-keyword> ASC
WITH (PAD_INDEX = OFF ,STATISTICS_NORECOMPUTE = OFF ,IGNORE_DUP_KEY = OFF ,ALLOW_ROW_LOCKS = ON ,ALLOW_PAGE_LOCKS = ON ON [ PRIMARY ]
ON [主要]







如果有人请提供相同的SQL脚本或建议我一样。



谢谢&此致,

Care Career

解决方案

我在这里遇到的最大问题是每个月有多少天。我努力寻找尼泊尔特有的规则,所以最后我使用了一个已知日期表(摘自这个网站 [ ^ ])。如果您知道规则,那么用适当的计算替换下面的硬编码值。

请注意,我使用了从2072年开始的标识列来生成年份数 - 只是我的懒惰!

 如果 存在选择 * 来自 INFORMATION_SCHEMA.TABLES 其中 TABLE_NAME =  '  DaysInMonth'
drop DaysInMonth;
创建 DaysInMonth

[NYear] int IDENTITY 2072 1 ),
[ 1 ] int
[ 2 ] int
[ 3 ] int
[ 4 ] int
[ 5 ] int
[ 6 ] int
[ 7 ] int
[ 8 ] int
[ 9 ] int
[ 10 ] int
[ 11 ] int
[ 12 ] int


insert into DaysInMonth values
31 32 31 32 31 30 30 29 30 29 30 30
,( 31 32 31 32 31 30 30 29 30 29 30 30
,( 31 32 31 32 31 30 30 30 29 29 30 31
,( 31 31 31 32 31 31 30 29 30 29 30 30
,( 31 31 32 31 31 31 30 29 30 29 30 30
,( 31 32 31 32 31 30 30 30 29 29 30 ,< span class =code-digit> 30 )
,( 31 32 31 32 31 30 30 30 29 30 29 31
,( 31 31 31 32 31 31 30 29 30 29 30 30
,( 31 31 32 31 31 31 30 29 30 29 30 30
,( 31 32 31 32 31 30 30 30 29 29 ,< span class =code-digit> 30 , 30
,( 31 31 32 32 31 30 30 ,< span class =code-digit> 30 , 29 30 30 30
,( 30 32 31 32 31 30 30 30 29 30 30 ,< span class =code-digit> 30 )
,( 31 31 32 31 31 30 30 30 ,< span class =code-digit> 30 , 29 30 30
,( 31 31 32 31 31 30 30 30 29 30 30 30
,( 31 32 31 32 30 31 30 30 29 30 30 30
,( 30 32 31 32 , 31 30 30 30 29 30 ,< span class =code-digit> 30 30
,( 31 31 32 31 31 31 30 ,< span class =code-digit> 30
29 30 30 30
,( 30 31 32 32 ,< span class =code-digit> 30 , 31 30 30 29 30 30 30
,( 30 32 31 32 31 30 30 30 29 30 30 30
,( 30 32 31 32 31 30 30 30 29 30 30 30

我使用了你的桌子的缩减版本来生成我的日历 - 主要是因为我不确定你试图用某些字段做什么,还因为有类似的事情 - 我不知道哪个您遵守工作日的规则。我的表看起来像这样......

如果存在(从INFORMATION_SCHEMA.TABLES中选择*,其中TABLE_NAME ='dim_time')
drop table [dim_time];
GO
CREATE TABLE [dbo]。[dim_time](
[calrownum] int IDENTITY(1,1)
,[YearLabel] int
,[QtrLabel] [nvarchar](20)NULL
,[MonthLabel] int
,[WeekLabel] int NULL
,[DayLabel] int
,[DayofWeek] [nvarchar](20)NULL
,[DayNumber] [int] NULL
,[EnglishDate] date NULL

)ON [PRIMARY]

EnglishDate 主要是为了我自己的利益,所以当我试图找出这个月的日子是如何确定的时候,我可以很容易地查看,但它也很方便确定星期几。 。

calrownum 不是必需的,但有时 select * from dim_time 不按预期顺序返回值,所以我使用

 选择 *  dim_time  order   by  calrownum 

以确保d ates的顺序正确。这比按年份标签输入订单更麻烦,月份标签,DayLabel



它现在变成了生成一个根据 DaysInMonth 中的数据,每个月的每一天行...注意我不使用游标迭代该表,而是 WHILE 循环而不是。另请注意,我刚刚对某些值进行了硬编码,您可能需要更改它们。

 声明  @sql   nvarchar (max)
声明 @ iteratorMonth int
声明 @ iteratorYear int
声明 @ iteratorDay int
DECLARE @ ParmDefinition nvarchar 500 );

set @ iteratorYear = 2072
WHILE @ iteratorYear < = 2091
BEGIN
set @ iteratorMonth = 1
set @ iteratorDay = 0
WHILE @ iteratorMonth < = 12
BEGIN
set @ sql = ' SELECT @retvalOUT = [' + CAST( @ iteratorMonth as varchar 2 来自DaysInMonth的))+ ' ],其中Nyear =' + CAST( @iteratorYear as varchar 4 ))
SET @ ParmDefinition = N ' @ retvalOUT int OUTPUT';

声明 @ retVal int
EXEC sp_executesql @ sql @ParmDefinition ,@ retvalOUT = @ retval OUTPUT ;

WITH q AS

SELECT 1 AS datum
UNION ALL
SELECT datum + < span class =code-digit> 1
FROM q
WHERE datum< @ retVal - NB< ;是正确的,不是< =

- 注意我目前没有WeekLabel,DayOfWeek或EnglishDate的值,因此它们被设置为NULL
INSERT INTO [dim_time] SELECT
@ iteratorYear ,CEILING(CAST( @ iteratorMonth AS decimal 4 2 ))/ 3 ), @ iteratorMonth NULL ,datum, NULL @ iteratorDay + datum, NULL
FROM q

SET < span class =code-sdkkeyword> @ iteratorMonth = @ iteratorMonth + 1
SET @ iteratorDay = @ iteratorDay + @ retVal
END
set @ iteratorYear = < span class =code-sdkkeyword> @ iteratorYear + 1
END ;

现在我重新访问该表以添加等效的英语日期和星期几(英文,抱歉)。请注意,这是基于2015年4月14日等于1 Baisakh 2072.I.e。我不使用公式计算日期,我只是在已知日期添加适当的天数。

   WITH  CTE  AS  

SELECT
rownum = ROW_NUMBER() OVER ORDER BY YearLabel,MonthLabel,DayLabel) ,YearLabel,MonthLabel,DayLabel
FROM [dim_time]

UPDATE G SET EnglishDate = DATEADD(dd,rownum,' 13-APR-2015'),[DayofWeek] = DATENAME(dw,DATEADD(dd,rownum,' 13-APR-2015'))
FROM [dim_time] G
LEFT JOIN CTE CTE ON CTE.YearLabel = G.YearLabel AND CTE.MonthLabel = G.MonthLabel AND CTE.DayLabel = G.DayLabel

在添加<之前我使用的是被删除的代码code> calrownum 列。我需要的那一列就是

  UPDATE  dim_time  set  EnglishDate = DATEADD(dd,calrownum,'  13-APR-2015'),[DayofWeek] = DATENAME(dw) ,DATEADD(dd,calrownum,'  13-APR-2015'))

在计算周数之前,我将一周的第一天设置为星期日。这是默认值,但我故意将其设置为突出显示本周在尼泊尔的一个星期日开始

并覆盖会话早期可能发生的任何其他事情。

设置DATEFIRST 7 

周数的计算取自 http://en.wikipedia.org/wiki / ISO_week_date [ ^ ]。您可能需要根据您使用的周编号系统进行更改 - 例如使用此方法,在2072年Chaitra 28,29,30是第1周(2073年)而不是第53周。

 < span class =code-keyword>更新 [dim_time]  set  WeekLabel =  CASE  
WHEN (DayNumber - DATEPART(dw,EnglishDate)+ 10 )/ 7 < 1 那么 52
< span class =code-keyword> WHEN (DayNumber - DATEPART(dw,EnglishDate)+ 10 )/ 7 > 52 那么 1
< span class =code-keyword> ELSE (DayNumber - DATEPART(dw,EnglishDate)+ 10 )/ 7 END



我的表现在包含1 Baisakh 2072和30 Chaitra 2091之间的每个日期(英国2015-04-14至2035-04-13)包含。



我使用以下查询来检查我每个月的天数是否正确< pre lang =sql> WITH q AS
SELECT *
FROM
SELECT
YearLabel,MonthLabel,COUNT(DayLabel) AS 来自 dim_time GROUP BY YearLabel,MonthLabel
as s
PIVOT

MAX(天)
FOR MonthLabel IN ([ 1 ],[< span class =code-digit> 2 ],[ 3 ],[ 4 ],[ 5 ],[ 6 ],[ 7 ],[ 8 ],[ 9 ],[ 10 ],[ 11 ],[ 12 ])
AS p)
选择 D.NYear,
[ 1 ] = CASE WHEN q。[ 1 ] = D. [ 1 ] 那么 ' True' ELSE ' False' END
[ 2 ] = CASE WHEN q。[ 2 ] = D。[ 2 ] 那么 ' True' ELSE ' False' END
[ 3 ] = CASE WHEN q。[ 3 ] = D。[ 3 ] 那么 ' True' ELSE ' False' END
[ 4 ] = CASE WHEN q。[ 4 ] = D。[ 4 ] THEN ' True' ELSE ' False' END
[ 5 ] = CASE WHEN q。[ 5 ] = D。[ 5 ] THEN ' True' ELSE ' False' END
[ 6 ] = CASE WHEN q。[ 6 ] = D. [< span class =code-digit> 6 ] 那么 ' True' ELSE ' False' END
[ 7 ] = CASE WHEN q。[ 7 ] = D。[ 7 ] 那么 ' True' ELSE ' 假' 结束
[ 8 ] = CASE WHEN q。[ 8 ] = D. [ 8 ] 那么 ' True' ELSE ' False' END
[ 9 ] = CASE WHEN q。[ 9 ] = D. [ 9 ] 那么 ' True' ELSE ' False' END
[ 10 ] = CASE WHEN q.[10]=D.[10] THEN 'True' ELSE 'False' END,
\t[11] = CASE WHEN q.[11]=D.[11] THEN 'True' ELSE 'False' END,
\t[12] = CASE WHEN q.[12]=D.[12] THEN 'True' ELSE 'False' END
from DaysInMonth D
LEFT OUTER JOIN q ON q.YearLabel = D.NYear

and used spot checking on a few dates to confirm the other details


Hi,

how to create and populate Date Time able for Nepal country for data warehouse.
I would like to have 20 years data in the below fileds according to Hindi calendar (for NEPAL Country)

CREATE TABLE [dbo].[dim_time](
    [YearLabel] [char](10) NULL,
    [QtrLabel] [nvarchar](20) NULL,
    [MonthLabel] [nvarchar](20) NULL,
    [WeekLabel] [nvarchar](20) NULL,
    [DayLabel] [nvarchar](20) NULL,
    [MonthSort] [int] NULL,
    [WeekSort] [int] NULL,
    [DaySort] [int] NULL,
    [DayofWeek] [nvarchar](20) NULL,
    [Month] [datetime] NULL,
    [TimeDate] [datetime] NULL,
    [TimeKey] [int] NOT NULL,
    [FiscalMonth] [nchar](20) NULL,
    [FiscalQtr] [nchar](20) NULL,
    [FiscalYear] [nchar](20) NULL,
    [WeekPeriod] [int] NULL,
    [DayNumber] [int] NULL,
    [workday_be] [tinyint] NULL,
    [workday_nl] [tinyint] NULL,
 CONSTRAINT [PK_DimTime] PRIMARY KEY CLUSTERED
(
    [TimeKey] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]




If anyone having please provide me SQL script for the same or advice me the same.

Thanks & Regards,
Care Career

解决方案

The biggest problem I had here was working out how many days there are in each month. I struggled to find the rules specific to Nepal, so in the end I used a table of known dates (taken from this website[^]). If you know the rules then replace the hard-coded values below with the appropriate calculations.
Note that I've used an identity column starting at 2072 to generate the year number - just laziness on my part!

if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'DaysInMonth')
    drop table DaysInMonth;
Create table DaysInMonth
(
    [NYear] int IDENTITY(2072,1),
    [1] int,
    [2] int,
    [3] int,
    [4] int,
    [5] int,
    [6] int,
    [7] int,
    [8] int,
    [9] int,
    [10] int,
    [11] int,
    [12] int
)

insert into DaysInMonth values
 (31,32,31,32,31,30,30,29,30,29,30,30)
,(31,32,31,32,31,30,30,29,30,29,30,30)
,(31,32,31,32,31,30,30,30,29,29,30,31)
,(31,31,31,32,31,31,30,29,30,29,30,30)
,(31,31,32,31,31,31,30,29,30,29,30,30)
,(31,32,31,32,31,30,30,30,29,29,30,30)
,(31,32,31,32,31,30,30,30,29,30,29,31)
,(31,31,31,32,31,31,30,29,30,29,30,30)
,(31,31,32,31,31,31,30,29,30,29,30,30)
,(31,32,31,32,31,30,30,30,29,29,30,30)
,(31,31,32,32,31,30,30,30,29,30,30,30)
,(30,32,31,32,31,30,30,30,29,30,30,30)
,(31,31,32,31,31,30,30,30,30,29,30,30)
,(31,31,32,31,31,30,30,30,29,30,30,30)
,(31,32,31,32,30,31,30,30,29,30,30,30)
,(30,32,31,32,31,30,30,30,29,30,30,30)
,(31,31,32,31,31,31,30,30,29,30,30,30)
,(30,31,32,32,30,31,30,30,29,30,30,30)
,(30,32,31,32,31,30,30,30,29,30,30,30)
,(30,32,31,32,31,30,30,30,29,30,30,30)

I used a cut-down version of your table to generate my calendar - mainly because I wasn't sure what you were trying to do with some of the fields, and also because of things like - I don't know which rules you follow for "working days". My table looks like this ...

if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'dim_time')
    drop table [dim_time];
GO
CREATE TABLE [dbo].[dim_time](
	[calrownum] int IDENTITY(1,1)
    ,[YearLabel] int
    ,[QtrLabel] [nvarchar](20) NULL
    ,[MonthLabel] int
    ,[WeekLabel] int NULL
    ,[DayLabel] int
    ,[DayofWeek] [nvarchar](20) NULL
    ,[DayNumber] [int] NULL
	,[EnglishDate] date NULL

) ON [PRIMARY]

The column EnglishDate was mainly for my own benefit so I could easily look things up when I was trying to find out how the days in the month were determined, but it is handy for determining the Day of the week as well.
The column calrownum isn't really necessary but sometimes select * from dim_time does not return the values in the expected order, so I use

select * from dim_time order by calrownum

to ensure that the dates are in the correct order. It's less hassle than typing order by YearLabel, MonthLabel,DayLabel

It now just becomes an exercise of generating a row for each day of each month based on the data in DaysInMonth...Note I do not use a cursor to iterate through that table but a WHILE loop instead. Also note that I've just hard-coded some values and you may want to change them.

declare @sql nvarchar(max)
declare @iteratorMonth int
declare @iteratorYear int
declare @iteratorDay int
DECLARE @ParmDefinition nvarchar(500);

set @iteratorYear = 2072
WHILE @iteratorYear <= 2091
BEGIN
	set @iteratorMonth = 1
	set @iteratorDay = 0
	WHILE @iteratorMonth <= 12
	BEGIN
		set @sql = 'SELECT @retvalOUT = [' + CAST(@iteratorMonth as varchar(2)) + '] from DaysInMonth where Nyear=' + CAST(@iteratorYear as varchar(4))
		SET @ParmDefinition = N'@retvalOUT int OUTPUT';

		declare @retVal int
		EXEC sp_executesql @sql, @ParmDefinition, @retvalOUT=@retval OUTPUT;

		 WITH q AS
        (
			SELECT  1 AS datum
			UNION ALL
			SELECT  datum + 1
			FROM    q
			WHERE datum < @retVal	--NB < is correct, not <=
        )
		-- Note I currently don't have values for WeekLabel, DayOfWeek or EnglishDate so they are being set to NULL
		INSERT INTO [dim_time] SELECT @iteratorYear,  CEILING(CAST(@iteratorMonth AS decimal(4,2)) / 3), @iteratorMonth, NULL, datum, NULL, @iteratorDay + datum, NULL
		FROM    q 

		SET @iteratorMonth = @iteratorMonth + 1
		SET @iteratorDay = @iteratorDay + @retVal
	END
	set @iteratorYear = @iteratorYear + 1
END;

Now I revisit the table to add the English date equivalent and the Day of the Week (in English, sorry). Note that this is based on 14-Apr-2015 being equal to 1 Baisakh 2072. I.e. I do not calculate the date using a formula, I just add the appropriate number of days onto a known date.

WITH CTE AS
(
    SELECT
    rownum = ROW_NUMBER() OVER (ORDER BY YearLabel, MonthLabel, DayLabel), YearLabel, MonthLabel, DayLabel
    FROM [dim_time]
)
UPDATE G SET EnglishDate = DATEADD(dd, rownum, '13-APR-2015'), [DayofWeek] = DATENAME(dw, DATEADD(dd, rownum, '13-APR-2015'))
FROM [dim_time] G
LEFT JOIN CTE CTE ON CTE.YearLabel = G.YearLabel AND CTE.MonthLabel = G.MonthLabel AND CTE.DayLabel = G.DayLabel

The struck out code is what I used before I added the calrownum column. With that column in place all I need is

UPDATE dim_time set EnglishDate = DATEADD(dd, calrownum, '13-APR-2015'), [DayofWeek] = DATENAME(dw, DATEADD(dd, calrownum, '13-APR-2015'))

Before calculating the Week number I set the first day of the week to Sunday. This is the default but I've deliberately set it to highlight that the week starts on a Sunday in Nepal
and to override anything else that might have happened earlier in the session.

set DATEFIRST 7

The calculation for the Week Number was taken from http://en.wikipedia.org/wiki/ISO_week_date[^]. You may need to change this depending on which week numbering system you use - for example using this method, in 2072 Chaitra 28,29,30 are week 1 (of 2073) rather than week 53.

Update [dim_time] set WeekLabel = CASE
    WHEN (DayNumber - DATEPART(dw, EnglishDate) + 10) / 7 < 1 THEN 52
    WHEN (DayNumber - DATEPART(dw, EnglishDate) + 10) / 7 > 52 THEN 1
    ELSE (DayNumber - DATEPART(dw, EnglishDate) + 10) / 7 END


My table now contains every date between 1 Baisakh 2072 and 30 Chaitra 2091 (UK 2015-04-14 to 2035-04-13) inclusive.

I used the following query to check I had the correct number of days in each month

WITH q AS(
SELECT *
FROM (
    SELECT 
        YearLabel, MonthLabel, COUNT(DayLabel) AS Days from dim_time GROUP BY YearLabel, MonthLabel
) as s
PIVOT
(
    MAX(Days)
    FOR MonthLabel IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
)AS p)
select D.NYear, 
	[1] = CASE WHEN q.[1]=D.[1] THEN 'True' ELSE 'False' END,
	[2] = CASE WHEN q.[2]=D.[2] THEN 'True' ELSE 'False' END,
	[3] = CASE WHEN q.[3]=D.[3] THEN 'True' ELSE 'False' END,
	[4] = CASE WHEN q.[4]=D.[4] THEN 'True' ELSE 'False' END,
	[5] = CASE WHEN q.[5]=D.[5] THEN 'True' ELSE 'False' END,
	[6] = CASE WHEN q.[6]=D.[6] THEN 'True' ELSE 'False' END,
	[7] = CASE WHEN q.[7]=D.[7] THEN 'True' ELSE 'False' END,
	[8] = CASE WHEN q.[8]=D.[8] THEN 'True' ELSE 'False' END,
	[9] = CASE WHEN q.[9]=D.[9] THEN 'True' ELSE 'False' END,
	[10] = CASE WHEN q.[10]=D.[10] THEN 'True' ELSE 'False' END,
	[11] = CASE WHEN q.[11]=D.[11] THEN 'True' ELSE 'False' END,
	[12] = CASE WHEN q.[12]=D.[12] THEN 'True' ELSE 'False' END
from DaysInMonth D
LEFT OUTER JOIN q ON q.YearLabel = D.NYear

and used spot checking on a few dates to confirm the other details


这篇关于如何为数据仓库的尼泊尔国家/地区创建和填充日期时间维度表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆