2015-09-29 4 views
0

У меня есть столбец с датами в форматеПреобразовать дата недели до календарной даты

год/number_of_week_in_year/number_of_day_of_the_week, например:

2015015 = 01.01.2015

Как написать запрос которые конвертируют эту дату в формат RRRRmmdd?

+2

Почему пятый день в году '01.01.2015'? 5-й день - либо «05.01.02015», либо «02.01.2015» (если календарная неделя началась с 29.12.2014, который, казалось, был так) –

+2

@TimSchmelter - я * считаю * это основано на концепции, что будний день 5 - четверг * (воскресенье - будний день 1) *, и поэтому первая «неделя» в 2015 году имеет только 3 дня , *** (ОП, уточните пожалуйста.) *** – MatBailie

+0

@MatBailie Да, в воскресенье свой первый день. – Kulis

ответ

2

Вот вам непроверенный ответ, так как у меня нет доступа к SQL Server, чтобы играть вокруг (на моем телефоне в данный момент).

Легкая часть, чтобы получить на значение даты в течение года ...

DATEADD(year, (input/1000) - 1900), 0) 

Затем вам нужно добавить определенное количество дней к нему ...
- 7 дней на каждую неделю (не включая 1-й недели)
- 1 день каждого дня недели

((input/10) % 100 - 1) * 7 
+ input % 10 

Тогда вычитая число дней в зависимости от дня недели, что год начался.

DATEPART(weekday, <your year as a date>) 


Который, кажется, дает ...

DATEADD(
    day, 
    ((input/10) % 100 - 1) * 7 
    + input % 10 
    - DATEPART(weekday, DATEADD(year, (input/1000) - 1900, 0)), 
    DATEADD(year, (input/1000) - 1900, 0) 
) 


Используя ваш пример ...

DATEADD(
    day, 
    ((2015015/10) % 100 - 1) * 7 
    + 2015015 % 10 
    - DATEPART(weekday, DATEADD(year, (2015015/1000) - 1900, 0)), 
    DATEADD(year, (2015015/1000) - 1900), 0) 
) 

=>

DATEADD(
    day, 
    (01 - 1) * 7 
    + 5 
    - DATEPART(weekday, DATEADD(year, 2015 - 1900, 0)), 
    DATEADD(year, 2015 - 1900, 0) 
) 

=>

DATEADD(
    day, 
    0 * 7 
    + 5 
    - DATEPART(weekday, '2015-01-01'), 
    '2015-01-01' 
) 

=>

DATEADD(
    day, 
    0 * 7 
    + 5 
    - 5, 
    '2015-01-01' 
) 

=>

'2015-01-01' 
+0

Отличный ответ, особенно на телефоне! Мне интересна первая строка 'DATEADD (год, (ввод/1000) - 1900), 0)'. Я полагаю, это основано на том, что 'input' является' int' правильным? Я предположил (по уважительной причине), что это была строка, поэтому я просто убедился, что вы не используете какой-нибудь классный новый халтур, о котором я не знаю! :-) –

+1

@MichaelMcMullin - Да, я должен был сказать, что это предположение, я просто пошел на пример, будучи «2015015 = 01.01.2015», который легко хранится как INT. – MatBailie

+0

@MatBailie Что я должен изменить в запросе, чтобы установить новый день начала недели, например, понедельник? – Kulis

1

Вы можете создать простую функцию, чтобы сделать это:

CREATE FUNCTION dbo.GetDate (@Date AS NVARCHAR(7)) 
RETURNS DATE 
AS 
BEGIN 
    DECLARE @WeekDayOfYearStart INT , 
     @WeekNum INT , 
     @DayInWeek INT , 
     @DateOut DATE; 

    SELECT @WeekNum = CONVERT(INT, RIGHT(LEFT(@Date, 6), 2)); 

    SELECT @DayInWeek = CONVERT(INT, RIGHT(@Date, LEN(@Date) - 6)); 

    SELECT @WeekDayOfYearStart = DATEPART(WEEKDAY, 
              LEFT(@Date, 4) + '0101'); 

    SELECT @DateOut = DATEADD(DAY, 
           (@WeekNum - 1) * 7 + @DayInWeek 
           - @WeekDayOfYearStart, 
           LEFT(@Date, 4) + '0101'); 
    RETURN @DateOut; 
END; 
GO 
+0

Спасибо. Я исправил это. –

0

Если я правильно понимаю вход, то varchar (10). Вы можете попробовать это

DECLARE @d varchar(10) 
set @d='2015/12/11' 
select 
    SUBSTRING(@d, 6, charindex('/', @d, 6) - 6) as week, 
    SUBSTRING(@d, charindex('/', @d, 6)+1, charindex('/', @d, len(@d) -  charindex('/', @d, 6))) as day, 
DateAdd(
    day, 
    cast(SUBSTRING(@d, charindex('/', @d, 6)+1, charindex('/', @d, len(@d) - charindex('/', @d, 6))) as int), 
    DateADD(
     week, 
     cast(SUBSTRING(@d, 6, charindex('/', @d, 6) - 6) as int), 
     DATEFROMPARTS(cast(SUBSTRING(@d, 0, 5) as int), 1,1) 
    ) 
) as d 
2

Вот простое решение, которое я бросил вместе, вероятно, не самый умный способ сделать это, но мы надеемся, имеет смысл:

DECLARE @inDate CHAR(7), 
     @inYear CHAR(4), 
     @inWeek INT, 
     @inDay INT, 
     @OutDate DATETIME; 

SET @inDate = '2015015'; 
SET @inYear = SUBSTRING(@inDate, 0, 5); 
SET @inWeek = CAST(SUBSTRING(@inDate, 5, 2) AS INT) - 1 -- Reduce by 1 because it will be added to start of year 
SET @inDay = CAST(SUBSTRING(@inDate, 7, 1) AS INT) 

SET @OutDate = CAST(@inYear + '-01-01' AS DATETIME) 
SET @OutDate = DATEADD(dd, -DATEPART(weekday, @OutDate) + @inDay, @OutDate) 
SET @OutDate = DATEADD(ww, @inWeek, @OutDate) 

PRINT @OutDate -- Gives Jan 1 2015 
Смежные вопросы