문제

SQL Server, 결정 론적 UDF를 통해 요일을 얻으려고합니다.

나는 이것이 가능해야한다고 확신하지만, 그것을 알아낼 수 없다.

업데이트 : 샘플 코드 ..

CREATE VIEW V_Stuff WITH SCHEMABINDING AS 
SELECT    
MD.ID, 
MD.[DateTime]
...
        dbo.FN_DayNumeric_DateTime(MD.DateTime) AS [Day], 
        dbo.FN_TimeNumeric_DateTime(MD.DateTime) AS [Time], 
...
FROM       {SOMEWHERE}
GO
CREATE UNIQUE CLUSTERED INDEX V_Stuff_Index ON V_Stuff (ID, [DateTime])
GO
도움이 되었습니까?

해결책

좋아, 나는 그것을 알아 냈다 ..

CREATE FUNCTION [dbo].[FN_DayNumeric_DateTime] 
(@DT DateTime)
RETURNS INT WITH SCHEMABINDING
AS 
BEGIN
DECLARE @Result int 
DECLARE  @FIRST_DATE        DATETIME
SELECT @FIRST_DATE = convert(DATETIME,-53690+((7+5)%7),112)
SET  @Result = datediff(dd,dateadd(dd,(datediff(dd,@FIRST_DATE,@DT)/7)*7,@FIRST_DATE), @DT)
RETURN (@Result)
END
GO

다른 팁

앞서 언급 한 솔루션에 대해 약간 유사한 접근 방식이지만 컴퓨터 열에는 함수 또는 인라인 내부에서 사용될 수있는 한 라이너입니다.

가정 :

  1. 1899-12-31 이전에는 데이트가 없습니다 (일요일)
  2. @@ datefirst = 7을 모방하고 싶습니다
  3. @DT는 SmallDateMe, DateTime, Date 또는 DateTime2 데이터 유형입니다.

오히려 다르고 싶다면 날짜 '18991231'을 평일 날짜로 변경하여 1. 1. Convert () 함수는 모든 작업을 만드는 데 중요합니다. 캐스트는 트릭을 수행하지 않습니다. :

(Datediff (Day, Convert (DateTime, '18991231', 112), @DT 7) % 7) + 1)

가져 왔습니다 데이트 일주일을 얻는 결정 론적 스칼라 기능

;
with 
Dates(DateValue) as 
(
    select cast('2000-01-01' as date)
    union all 
    select dateadd(day, 1, DateValue) from Dates where DateValue < '2050-01-01'
)
select 
    year(DateValue) * 10000 + month(DateValue) * 100 + day(DateValue) as DateKey, DateValue,        
    datediff(day, dateadd(week, datediff(week, 0, DateValue), 0), DateValue) + 2 as DayOfWeek,
    datediff(week, dateadd(month, datediff(month, 0, DateValue), 0), DateValue) + 1 as WeekOfMonth,
    datediff(week, dateadd(year, datediff(year, 0, DateValue), 0), DateValue) + 1 as WeekOfYear
    from Dates option (maxrecursion 0)

나는이 게시물이 낡았다는 것을 알고 있지만, 비슷한 일을하려고 노력했고 다른 해결책을 생각해 내고 후손을 위해 게시 할 것이라고 생각했습니다. 게다가 나는 약간의 검색을 했고이 질문에서 많은 내용을 찾지 못했습니다.

제 경우에는 계산 된 열이 지속 된 열을 사용하려고했는데, 이는 계산이 결정적이어야합니다. 내가 사용한 계산은 다음과 같습니다.

datediff(dd,'2010-01-03',[DateColumn]) % 7 + 1

아이디어는 테이블에서 가능한 날짜 (이 경우, 2010 년 1 월 3 일) 이전에 발생할 수있는 알려진 일요일을 파악한 다음 일요일 이후의 일수의 모듈로 7 + 1을 계산하는 것입니다.

문제는 함수 호출에 문자 그대로 날짜를 포함시키는 것만으로는 결정적이지 않은 것으로 표시되기에 충분하다는 것입니다. 정수 0을 사용하여 SQL Server의 경우 1900 년 1 월 1 일 일요일 인 Epoch를 표현하여이를 해결할 수 있습니다.

datediff(dd,0,[DateColumn]) % 7 + 1

+1은 DateFirst가 7 (기본값)으로 설정되었을 때 DatePart (DW, [DateColumn])와 동일하게 결과를 작동시킵니다.

나는 또한 1 일 때 '일요일'이있을 때 '월요일'...

SQL에는 이미 내장 된 기능이 있습니다.

SELECT DATEPART(weekday, '2009-11-11')

편집하다: 정말로 결정 론적 UDF가 필요하다면 :

CREATE FUNCTION DayOfWeek(@myDate DATETIME ) 
RETURNS int
AS
BEGIN
RETURN DATEPART(weekday, @myDate)
END
GO
SELECT dbo.DayOfWeek('2009-11-11')

다시 편집하십시오: 이것은 실제로 잘못되었습니다 DATEPART(weekday) 결정 론적이지 않습니다.

업데이트: DATEPART(weekday) 의존하기 때문에 비 결정적입니다 DATEFIRST (원천).
당신은 그것을 변경할 수 있습니다 SET DATEFIRST 그러나 저장된 기능 안에서 부를 수는 없습니다.

다음 단계는 그렇습니다 나만의 구현을하십시오, 당신이 선호하는 날짜를 그 안에 사용합니다 (예 : 예를 들어, 그것을 전혀 고려하지 않음 월요일 첫날).

제안 된 솔루션에는 한 가지 문제가 있습니다. 토요일에 0을 반환합니다. 우리가 호환되는 것을 찾고 있다고 가정합니다 DATEPART(WEEKDAY) 이것은 문제입니다.

단순한 것은 없습니다 CASE 그래도 진술은 해결되지 않습니다.

함수를 만들고 @dbdate varchar (8)를 입력 변수로 사용하십시오.

다음을 반환하십시오.

RETURN (DATEDIFF(dd, -1, convert(datetime, @dbdate, 112)) % 7)+1;

값 112는 SQL 스타일 yyyymmdd입니다.

Datediff는 문자열 입력을받지 않기 때문에 결정적입니다. 문자열을 받으면 내부적으로 DateTime 객체로 변환되기 때문에 더 이상 작동하지 않습니다. 결정 론적이지 않습니다.

무엇을 찾고 있는지 확실하지 않지만 이것이 웹 사이트의 일부라면이 PHP 기능을 사용해보십시오. http://php.net/manual/en/function.date.php

function weekday($fyear, $fmonth, $fday) //0 is monday
{
  return (((mktime ( 0, 0, 0, $fmonth, $fday, $fyear) - mktime ( 0, 0, 0, 7, 17,   2006))/(60*60*24))+700000) % 7;
}

요일? DatePart 만 사용하지 않는 이유는 무엇입니까?

DATEPART(weekday, YEAR_DATE)

다음과 같이 선택할 수는 없습니다.

SELECT DATENAME(dw, GETDATE());
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top