powered by simpleCommunicator - 2.0.18     © 2024 Programmizd 02
Map
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Нужна функция "ближайший год"
8 сообщений из 8, страница 1 из 1
Нужна функция "ближайший год"
    #40138182
Протобуранец
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В строках есть дата-время вида
Sep 22 13:14:06
Без года. Время может убегать/отставать вплоть до нескольких суток, раньше оно игнорировалось, но теперь с ним тоже надо работать, для статистики. Кроме того, есть хорошая дата-время из источника с надежной синхронизацией, когда эта строка была получена. Хотелось бы конвертить эти строки в дату-время так, чтобы в районе 1 января не было косяков. То есть, если есть пары записей
2023-12-31 23:50:40.000 | Jan 1 00:01:02 2024-01-01 01:02:00.001 | Dec 31 23:59:00
То в первом случае надо получить
2024 Jan 1 00:01:02
Во втором -
2023 Dec 31 23:59:00
Как бы сделать покрасивше и побыстрее? Строк много.
...
Рейтинг: 0 / 0
Нужна функция "ближайший год"
    #40138183
Неуловимый Джо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну как-то так.
Хотя надо решить что делать, если разница в секундах будет одинаковая.
От outer apply можно избавиться, но тогда длинные выражения будут в условии с кучей скобок, не красиво.
Код: SQL
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
declare @dt table(
  dt datetime
)
insert into @dt (dt) values('20231231 23:50:40.000'), ('20240101 01:02:00.001')

select
     d.dt
    ,NearestYear = iif( datediff(second, y.YearBack, d.dt) > datediff(second, d.dt, y.YearForward)
                       ,y.YearBack
                       ,y.YearForward
                      )
  from @dt as d
  outer apply (
    select
       YearBack    = datefromparts(year(d.dt), 1, 1)
      ,YearForward = datefromparts(year(d.dt) + 1, 1, 1)
  ) as y
...
Изменено: 27.10.2023, 11:52 - Неуловимый Джо
Рейтинг: 0 / 0
Нужна функция "ближайший год"
    #40138184
Протобуранец
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то не то получилось.
dt NearestYear
2023-12-31 23:50:40.000 2023-01-01
2024-01-01 01:02:00.000 2025-01-01
Наверное, я плохо объяснил. Вот у нас есть строка:
Jan 1 00:01:02
Про дату-время в этой строке мы знаем, что она неточная, но не месяцы. Максимум - пара дней. Кроме того, у нас есть дата-время, когда мы эту строку получили:
2023-12-31 23:50:40.000
Нам надо добавить к исходной строке год, чтобы потом конвертнуть ее в дата-время и дальше с ней работать как с датой. Очевидно, что время на глупом устройстве убежало, и нам нужно добавить 2024 год, чтобы получилось вот так:
2024 Jan 1 00:01:02
...
Рейтинг: 0 / 0
Нужна функция "ближайший год"
    #40138185
Протобуранец
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если в коде поменять знак больше на меньше, то получается так
dt NearestYear
2023-12-31 23:50:40.000 2024-01-01
2024-01-01 01:02:00.000 2024-01-01
Если мы попытаемся применить это к нашим данным
2023-12-31 23:50:40.000 | Jan 1 00:01:02 2024-01-01 01:02:00.001 | Dec 31 23:59:00
то мы в обоих случаях добавим 2024, в то время как во второй строке нам надо добавлять 2023.
...
Изменено: 27.10.2023, 13:20 - Протобуранец
Рейтинг: 0 / 0
Нужна функция "ближайший год"
    #40138186
Протобуранец
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Получается, мы должны сделать три конвертации строка - дата-время
Jan 1 00:01:02
2022 Jan 1 00:01:02 2023 Jan 1 00:01:02 2024 Jan 1 00:01:02
И посмотреть, что из них ближе всего к времени, когда мы получили эту строку. Дороговато получается.
...
Рейтинг: 0 / 0
Нужна функция "ближайший год"
    #40138187
Протобуранец
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Заготовка для функции. Но мне этот подход не нравится.
Код: SQL
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
declare @dt datetime -- input
declare @st nchar(15) -- input
declare @rs datetime -- output

--select @dt = '2023-12-31 23:50:40.000', @st = 'Dec 31 23:59:00'
--select @dt = '2024-01-01 23:50:40.000', @st = 'Dec 31 23:59:00'
--select @dt = '2023-12-31 23:50:40.000', @st = 'Jan 1 00:01:02'
select @dt = '2024-01-01 23:50:40.000', @st = 'Jan 1 00:01:02'

declare @d1 datetime, @d2 datetime, @d3 datetime
declare @y int

set @y = datepart(year, @dt)

set @d1 = convert(datetime, convert(nchar(4), @y - 1) + ' ' + @st)
set @d2 = convert(datetime, convert(nchar(4), @y) + ' ' + @st)
set @d3 = convert(datetime, convert(nchar(4), @y + 1) + ' ' + @st)

if 2 > datediff(month, @dt, @d1) set @rs = @d1
if 2 > datediff(month, @dt, @d2) set @rs = @d2
if 2 > datediff(month, @dt, @d3) set @rs = @d3

select @rs
...
Рейтинг: 0 / 0
Нужна функция "ближайший год"
    #40138188
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Протобуранец [игнорируется] 

я так думаю, достаточно понимания, что мы на границе года, остальное нас не интересует
Код: SQL
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
select
  dt, st,
  convert( datetime,
    convert( char(5),
      year(dt) +
      case
        when month(dt) = 12 and month(st) = 1 then 1
        when month(dt) = 1  and month(st) = 12 then -1
        else 0
      end
    ) + st
  ) rs
from
  (values
    (cast('2023-12-31 23:50:40.000' as datetime), cast('Dec 31 23:59:00' as varchar(15))),
    ('2024-01-01 23:50:40.000', 'Dec 31 23:59:00'),
    ('2023-12-31 23:50:40.000', 'Jan 1 00:01:02'),
    ('2024-01-01 23:50:40.000', 'Jan 1 00:01:02'),
    ('2023-06-01 23:50:40.000', 'May 31 00:01:02')
  ) v(dt, st)
...
Рейтинг: 1 / 0
Нравится: Протобуранец
Нужна функция "ближайший год"
    #40138190
Протобуранец
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, так правильней. Спасибо.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Нужна функция "ближайший год"
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (0):
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]