#sql #sql-server #tsql
#sql #sql-сервер #tsql
Вопрос:
IF OBJECT_ID('dbo.DimensionDate', 'U') IS NOT NULL
DROP TABLE dbo.DimensionDate
/**********************************************************************************/
CREATE TABLE [dbo].[DimensionDate]
( [DateKey] INT primary key,
[Date] DATETIME,
[FullDate] CHAR(10),-- Date in dd-MM-yyyy format
[DayOfMonth] VARCHAR(2), -- Field will hold day number of Month
[DaySuffix] VARCHAR(4), -- Apply suffix as 1st, 2nd ,3rd etc
[DayName] VARCHAR(9), -- Contains name of the day, Sunday, Monday
[DayOfWeekIRE] CHAR(1),-- First Day Monday=1 and Sunday=7
[DayOfWeekInMonth] VARCHAR(2), --1st Monday or 2nd Monday in Month
[DayOfWeekInYear] VARCHAR(2),
[DayOfQuarter] VARCHAR(3),
[DayOfYear] VARCHAR(3),
[WeekOfMonth] VARCHAR(1),-- Week Number of Month
[WeekOfQuarter] VARCHAR(2), --Week Number of the Quarter
[WeekOfYear] VARCHAR(2),--Week Number of the Year
[Month] VARCHAR(2), --Number of the Month 1 to 12
[MonthName] VARCHAR(9),--January, February etc
[MonthOfQuarter] VARCHAR(2),-- Month Number belongs to Quarter
[Quarter] CHAR(1),
[QuarterName] VARCHAR(9),--First,Second..
[Year] CHAR(4),-- Year value of Date stored in Row
[YearName] CHAR(7), --CY 2012,CY 2013
[MonthYear] CHAR(10), --Jan-2013,Feb-2013
[MMYYYY] CHAR(6),
[FirstDayOfMonth] DATE,
[LastDayOfMonth] DATE,
[FirstDayOfQuarter] DATE,
[LastDayOfQuarter] DATE,
[FirstDayOfYear] DATE,
[LastDayOfYear] DATE,
[IsHolidayIRE] BIT,-- Flag 1=National Holiday, 0-No National Holiday
[IsWeekday] BIT,-- 0=Week End ,1=Week Day
[HolidayIRE] VARCHAR(50),--Name of Holiday in US
[IsHolidayUK] BIT Null,-- Flag 1=National Holiday, 0-No National Holiday
[HolidayUK] VARCHAR(50) Null, --Name of Holiday in UK
[PastOrFuture] BIT Null -- Flag 0=Past, 1=Future
)
GO
TRUNCATE Table Dbo.DimensionDate
/********************************************************************************************/
--Specify Start Date and End date here
--Value of Start Date Must be Less than Your End Date
DECLARE @StartDate DATETIME = '04/01/2012' --Starting value of Date Range
DECLARE @EndDate DATETIME = '04/01/2015' --End Value of Date Range
--Temporary Variables To Hold the Values During Processing of Each Date of Year
DECLARE
@DayOfWeekInMonth INT,
@DayOfWeekInYear INT,
@DayOfQuarter INT,
@WeekOfMonth INT,
@CurrentYear INT,
@CurrentMonth INT,
@CurrentQuarter INT
/*Table Data type to store the day of week count for the month and year*/
DECLARE @DayOfWeek TABLE (DOW INT, MonthCount INT, QuarterCount INT, YearCount INT)
INSERT INTO @DayOfWeek VALUES (1, 0, 0, 0)
INSERT INTO @DayOfWeek VALUES (2, 0, 0, 0)
INSERT INTO @DayOfWeek VALUES (3, 0, 0, 0)
INSERT INTO @DayOfWeek VALUES (4, 0, 0, 0)
INSERT INTO @DayOfWeek VALUES (5, 0, 0, 0)
INSERT INTO @DayOfWeek VALUES (6, 0, 0, 0)
INSERT INTO @DayOfWeek VALUES (7, 0, 0, 0)
--Extract and assign various parts of Values from Current Date to Variable
DECLARE @CurrentDate AS DATETIME = @StartDate
SET @CurrentMonth = DATEPART(MM, @CurrentDate)
SET @CurrentYear = DATEPART(YY, @CurrentDate)
SET @CurrentQuarter = DATEPART(QQ, @CurrentDate)
SET @startDate = GETDATE()
/********************************************************************************************/
--Proceed only if Start Date(Current date ) is less than End date you specified above
WHILE @CurrentDate < @EndDate
BEGIN
/*Begin day of week logic*/
/*Check for Change in Month of the Current date if Month changed then
Change variable value*/
IF @CurrentMonth != DATEPART(MM, @CurrentDate)
BEGIN
UPDATE @DayOfWeek
SET MonthCount = 0
SET @CurrentMonth = DATEPART(MM, @CurrentDate)
END
/* Check for Change in Quarter of the Current date if Quarter changed then change
Variable value*/
IF @CurrentQuarter != DATEPART(QQ, @CurrentDate)
BEGIN
UPDATE @DayOfWeek
SET QuarterCount = 0
SET @CurrentQuarter = DATEPART(QQ, @CurrentDate)
END
/* Check for Change in Year of the Current date if Year changed then change
Variable value*/
IF @CurrentYear != DATEPART(YY, @CurrentDate)
BEGIN
UPDATE @DayOfWeek
SET YearCount = 0
SET @CurrentYear = DATEPART(YY, @CurrentDate)
END
-- Set values in table data type created above from variables
UPDATE @DayOfWeek
SET
MonthCount = MonthCount 1,
QuarterCount = QuarterCount 1,
YearCount = YearCount 1
WHERE DOW = DATEPART(DW, @CurrentDate)
SELECT
@DayOfWeekInMonth = MonthCount,
@DayOfQuarter = QuarterCount,
@DayOfWeekInYear = YearCount
FROM @DayOfWeek
WHERE DOW = DATEPART(DW, @CurrentDate)
/ Логика конечного дня недели/
/ * Заполните таблицу измерений значениями*/
INSERT INTO [dbo].[DimensionDate]
SELECT
CONVERT (char(8),@CurrentDate,112) as DateKey,
@CurrentDate AS Date,
CONVERT (char(10),@CurrentDate,103) as FullDate,
DATEPART(DD, @CurrentDate) AS DayOfMonth,
--Apply Suffix values like 1st, 2nd 3rd etc..
CASE
WHEN DATEPART(DD,@CurrentDate) IN (11,12,13)
THEN CAST(DATEPART(DD,@CurrentDate) AS VARCHAR) 'th'
WHEN RIGHT(DATEPART(DD,@CurrentDate),1) = 1
THEN CAST(DATEPART(DD,@CurrentDate) AS VARCHAR) 'st'
WHEN RIGHT(DATEPART(DD,@CurrentDate),1) = 2
THEN CAST(DATEPART(DD,@CurrentDate) AS VARCHAR) 'nd'
WHEN RIGHT(DATEPART(DD,@CurrentDate),1) = 3
THEN CAST(DATEPART(DD,@CurrentDate) AS VARCHAR) 'rd'
ELSE CAST(DATEPART(DD,@CurrentDate) AS VARCHAR) 'th'
END AS DaySuffix,
DATENAME(DW, @CurrentDate) AS DayName,
-- check for day of week as Per US and change it as per UK format
CASE DATEPART(DW, @CurrentDate)
WHEN 1 THEN 7
WHEN 2 THEN 1
WHEN 3 THEN 2
WHEN 4 THEN 3
WHEN 5 THEN 4
WHEN 6 THEN 5
WHEN 7 THEN 6
END
AS DayOfWeekIRE,
@DayOfWeekInMonth AS DayOfWeekInMonth,
@DayOfWeekInYear AS DayOfWeekInYear,
@DayOfQuarter AS DayOfQuarter,
DATEPART(DY, @CurrentDate) AS DayOfYear,
DATEPART(WW, @CurrentDate) 1 - DATEPART(WW, CONVERT(VARCHAR,
DATEPART(MM, @CurrentDate)) '/1/' CONVERT(VARCHAR,
DATEPART(YY, @CurrentDate))) AS WeekOfMonth,
(DATEDIFF(DD, DATEADD(QQ, DATEDIFF(QQ, 0, @CurrentDate), 0),
@CurrentDate) / 7) 1 AS WeekOfQuarter,
DATEPART(WW, @CurrentDate) AS WeekOfYear,
DATEPART(MM, @CurrentDate) AS Month,
DATENAME(MM, @CurrentDate) AS MonthName,
CASE
WHEN DATEPART(MM, @CurrentDate) IN (1, 4, 7, 10) THEN 1
WHEN DATEPART(MM, @CurrentDate) IN (2, 5, 8, 11) THEN 2
WHEN DATEPART(MM, @CurrentDate) IN (3, 6, 9, 12) THEN 3
END AS MonthOfQuarter,
DATEPART(QQ, @CurrentDate) AS Quarter,
CASE DATEPART(QQ, @CurrentDate)
WHEN 1 THEN 'First'
WHEN 2 THEN 'Second'
WHEN 3 THEN 'Third'
WHEN 4 THEN 'Fourth'
END AS QuarterName,
DATEPART(YEAR, @CurrentDate) AS Year,
'CY ' CONVERT(VARCHAR, DATEPART(YEAR, @CurrentDate)) AS YearName,
LEFT(DATENAME(MM, @CurrentDate), 3) '-' CONVERT(VARCHAR,
DATEPART(YY, @CurrentDate)) AS MonthYear,
RIGHT('0' CONVERT(VARCHAR, DATEPART(MM, @CurrentDate)),2)
CONVERT(VARCHAR, DATEPART(YY, @CurrentDate)) AS MMYYYY,
CONVERT(DATETIME, CONVERT(DATE, DATEADD(DD, - (DATEPART(DD,
@CurrentDate) - 1), @CurrentDate))) AS FirstDayOfMonth,
CONVERT(DATETIME, CONVERT(DATE, DATEADD(DD, - (DATEPART(DD,
(DATEADD(MM, 1, @CurrentDate)))), DATEADD(MM, 1,
@CurrentDate)))) AS LastDayOfMonth,
DATEADD(QQ, DATEDIFF(QQ, 0, @CurrentDate), 0) AS FirstDayOfQuarter,
DATEADD(QQ, DATEDIFF(QQ, -1, @CurrentDate), -1) AS LastDayOfQuarter,
CONVERT(DATETIME, '01/01/' CONVERT(VARCHAR, DATEPART(YY,
@CurrentDate))) AS FirstDayOfYear,
CONVERT(DATETIME, '12/31/' CONVERT(VARCHAR, DATEPART(YY,
@CurrentDate))) AS LastDayOfYear,
NULL AS IsHolidayIRE,
CASE DATEPART(DW, @CurrentDate)
WHEN 1 THEN 0
WHEN 2 THEN 1
WHEN 3 THEN 1
WHEN 4 THEN 1
WHEN 5 THEN 1
WHEN 6 THEN 1
WHEN 7 THEN 0
END AS IsWeekday,
NULL AS HolidayIRE, Null, Null
UPDATE
DimensionDate
SET [PastOrFuture] =
CASE
WHEN @StartDate <= [DATE] THEN 0
ELSE 1
END
УСТАНОВИТЕ @currentDate = DATEADD(DD, 1, @currentDate)
КОНЕЧНЫЙ ВЫБОР * ИЗ DimensionDate
Сообщение 213, уровень 16, состояние 1, строка 99 Имя столбца или количество предоставленных значений не соответствует определению таблицы.
Я просто хочу исправить обновление в нижней части этого кода, не позволяя мне обновлять столбец PastOrFuture до 0 или 1 в зависимости от даты
Он работает идеально, если я удаляю свое обновление и возвращаю значение null.
Комментарии:
1. Как это не работает? Ошибка, неожиданные результаты, что-то еще?
2. Сообщение 213, уровень 16, состояние 1, строка 99 Имя столбца или количество предоставленных значений не соответствует определению таблицы. Он работает идеально, если я удаляю свое обновление и возвращаю значение null.
3. Вам нужно упростить этот код. Можете ли вы опубликовать общее представление о том, с чем вам нужна помощь? Можете ли вы попробовать удалить части кода, которые, как вы знаете, не являются проблемой? Нам нужно больше общего представления о том, что происходит, а что не происходит.
4. У вас
insert
короткий столбец 1… у вас есть 3 столбца послеHolidayIRE
, но ваша вставка имеет только 2 нуля после случая дляHolidayIRE
.5. Кроме того, попробуйте лучше отформатировать свой кодер. Это поможет вам найти ошибки такого рода.
Ответ №1:
Попробуйте удалить свой оператор update и заменить следующий код на и проверить?
.... NULL AS HolidayIRE, Null, Null,
CASE
WHEN @StartDate <= [DATE] THEN 0
ELSE 1
END
FROM DimensionDate
Я думаю, вы пытаетесь обновить insert. Вы можете вычислить прошлое будущего в самом операторе select
Ответ №2:
Ваш INSERT
into DimensionDate
короткий столбец.
У вас есть 3 столбца после HolidayIRE
, но у insert
вас есть только 2 NULLS
после случая для HolidayIRE
Либо добавьте список столбцов в insert
, либо добавьте еще NULL
один в конец insert
.
Если на то пошло, не нужно UPDATE
просто указывать свой случай в конце INSERT
и делать случай последним столбцом и вставлять PastOrFuture на лету…
CASE
WHEN @StartDate <= [DATE] THEN 0
ELSE 1
END
Ответ №3:
Вы не указали pastorfuture, посчитайте свои поля по сравнению с таблицей. у вас есть HolidayIRE, null, null, а в таблице указано HolidayIRE, IsHolidayUK, HolidayUK, PastOrFuture