2017-09-14 6 views
0

이 모든 곳에서 소리가 나면 용서해주십시오. SQL 전문가는 아닙니다.SQL - 날짜 시간 열을 가장 가까운 평일로 설정하십시오.

그래서 특정 테이블에 삽입하거나 업데이트하는 몇 가지 저장 프로 시저가 있습니다.

현재 각각의 저장 프로 시저에 대해 select datetime 열 (우리는 MailingDate라고 부름)에 대한 논리가있어 select 절에서 다양한 case 문을 사용하여 금요일 또는 토요일 중 하나에 설정합니다. 어떤 주말에 떨어지는 지. 그냥 참조의 프레임에 대해, 그 논리는 다음과 같습니다

구성 테이블 (아무 PK-에 있습니다

> FK 관계 : 기본적으로

alias.MailingDate = 
CASE DATEPART(WEEKDAY, DATEADD(dd, aliasTwo.MailingDays, aliasThree.DateScheduled)) 
    WHEN 7 THEN 
      CASE aliasTwo.MailingDays 
       WHEN 0 THEN DATEADD(DAY, 2, DATEADD(dd, aliasTwo.MailingDays, aliasThree.DateScheduled)) -- Saturday is 7, MailingDate fell on Saturday the 1st, goto Monday. 
       ELSE DATEADD(DAY, -1, DATEADD(dd, aliasTwo.MailingDays, aliasThree.DateScheduled))  -- Saturday is 7, MailingDate fell on Saturday, goto Friday. 
      END 
    WHEN 1 THEN DATEADD(DAY, 1, DATEADD(dd, aliasTwo.MailingDays, aliasThree.DateScheduled))    -- Sunday is 1, MailingDate needs to goto Monday. 
    ELSE DATEADD(dd, aliasTwo.MailingDays, aliasThree.DateScheduled)          -- MailingDate fell on Weekday. 
END, -- MailingDate 

,이 설명하기 위해 그 논리를 교체해야

Configurations: 

|ConfigurationId|  Keyword  |  Value   | 
------------------------------------------------------------ 
|1    |MailingDays:Sunday |Value1    | 
|2    |MailingDays:Monday |     | 
|3    |MailingDays:Tuesday |Value2    | 
|4    |MailingDays:Wednesday|Value3|Value1  | 
|5    |MailingDays:Thursday |     | 
|6    |MailingDays:Friday |Value1|Value2|Value3| 
|7    |MailingDays:Saturday |Value3|Value1  | 

각 행은 평일를 나타내며,이 주중에이 같은 (가 동적하는 목표이기 때문에 값 열에서 항목 언제든지 변경 될 수 있습니다)을 보이는 다른 테이블)에 lis로 구분 된 파이프가 들어있는 varchar() 값 열입니다. 다른 테이블에서 varchar() 값 중 t. 아이디어는 위에서 본 메일 링 날짜를 업데이트 할 때이 테이블을 동적으로 사용하여 각 특정 값 (Value1, Value2, Value3)을 확인하고, 각 요일에 어떤 값이 부여되는지, 그리고 메일 링 날짜를로 이동해야합니다. 가장 가까운 평일.

예를 들어 Value1의 모든 메일 링 날짜를 계산하는 경우 구성 테이블을 동적으로 검색해야하며 Value1은 일요일, 수요일, 금요일 및 토요일에 할당 된 것을 확인하고 다음 위치로 이동해야합니다. 가장 가까운 평일은 aliasTwo.MailingDays의 요일에 따라 달라집니다. 이 경우 aliasTwo.MailingDays가 월요일 인 경우 alias.MailingDate를 일요일로 설정해야합니다. aliasTwo.MailingDays가 화요일 인 경우 alias.MailingDate를 수요일로 이동해야합니다.

alias.MailingDays이 다른 두 평일 사이의 등거리이다 평일이면위한 특별한 사용 사례가있다 : 예를 들어

내가 값 2의 구성 테이블을 검색하는 경우, 내가 값 2가 기인하는 것으로 볼 것은 화요일과 금요일. 따라서이 경우 aliasTwo.MailingDays가 일요일이면 alias.MailingDate는 다음 주 평일로 이동합니다. 이 경우, 일요일은 금요일과 화요일부터 등거리이므로 화요일로 이동합니다.

이것은 본질적으로 일어날 일입니다. SQL은 확실히 나의 가장 강력한 언어가 아니기 때문에이 문제에 대한 유익한 도움을 많이 주시면 감사하겠습니다.

추가 설명이 필요하면 알려주십시오.

감사합니다.

답변

0

일 사이의 매핑 테이블을 만들고 그날로 이동합니다. 그런 다음 해당 날짜 맵핑에 대한 별도의 테이블 맵핑 값을 작성하십시오. 오버로드 된 열을 없애고 미친 날짜 변환 논리처럼 들리는 데서 그 날짜 매핑 테이블을 그대로 유지할 수 있습니다.

if object_id('tempdb.dbo.#DateMappings') is not null drop table #DateMappings 
create table #DateMappings 
(
    MappingId int identity(1,1), 
    ThisDOW int, 
    MapsToThisDOW int 

    primary key clustered (MappingId), 
    unique (THisDOw, MapsToTHisDOW) 
) 

-- This would be replaced with what your actual logic is; i'm not going to try to figure out your rules 
;with nums (num) as 
(
    select 1 union all 
    select 2 union all 
    select 3 union all 
    select 4 union all 
    select 5 union all 
    select 6 union all 
    select 7 
) 
insert into #DateMappings 
(
    ThisDOW, 
    MapsToThisDOW 
) 
select 
    ThisDOW = a.num, 
    MapsToThisDOW = b.num 
from nums a 
cross join nums b 

if object_id('tempdb.dbo.#ValueDateMappings') is not null drop table #ValueDateMappings 
create table #ValueDateMappings 
(
    Value varchar(100), 
    DateMappingId int 

    primary key clustered (Value, DateMappingId) 
) 

-- This maps a SINGLE value to a SINGLE mapping construct. You can then use the information for that date mapping to construct or adjust the mailing date as you see fit 
insert into #ValueDateMappings 
values 
    ('Value 1', 1), 
    ('value 1', 3) 
    -- ...etc