Click here to Skip to main content
15,893,266 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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)

SQL
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
Posted
Updated 20-Mar-15 0:08am
v3
Comments
OriginalGriff 20-Mar-15 5:49am    
This is not a good question - we cannot work out from that little what you are trying to do.
Remember that we can't see your screen, access your HDD, or read your mind.
Use the "Improve question" widget to edit your question and provide better information.
vibsg 20-Mar-15 6:03am    
Done Now. I hope now it make sense. Thanks
CHill60 21-Mar-15 18:02pm    
Just let you know I am looking into how we could do this. I'll get back to you when I can :)

1 solution

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!
SQL
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
SQL
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.
SQL
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.
SQL
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
SQL
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.
SQL
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
SQL
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
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900