Member 14816845 Ответов: 2

Как получить временной интервал для каждой записи в MSQL


Привет Команда,

у меня есть таблица, в которой доступны записи со значениями datetime.

мне нужно получить ежедневный обработанный отчет с дополнительным столбцом в качестве временного интервала.

я разделил день на 96 временных интервалов по 15 минут каждый.

Таким образом, если запись datetime имеет значение "2020-04-29 08:31:05.907", то она должна находиться под временным интервалом 35, то есть между 08:30 и 08:45

Что я уже пробовал:

у меня есть приведенный ниже запрос, который разделяет день, но мне нужно присоединиться к моей таблице транзакций, чтобы получить временной интервал конкретной записи

With temp
As
(
   SELECT 1 as Time_ID, RIGHT(CONVERT(VARCHAR(16),
   DATEADD(day, DATEDIFF(day,0,GETDATE()),0),120),15)  as Time_Slot
   
   UNION ALL

   SELECT Time_ID+1 ,RIGHT(CONVERT(VARCHAR(16),
   DATEADD(minute, Time_ID*15,DATEADD(day, DATEDIFF(day,0,GETDATE()),0) ) ,120),15)

   FROM temp
   WHERE DATEADD(minute, Time_ID*15,DATEADD(day, DATEDIFF(day,0,GETDATE()),0)) < DATEADD(day,DATEDIFF(day,0,GETDATE())+1,0)
)select * from temp 

CHill60

Вы опубликовали только часть своего запроса

Member 14816845

(меньше, чем)функция dateadd(день,функция datediff(день,0,getdate ()) для+1,0))выберите * от темп

это недостающая часть

меньше символа(& lt;) здесь не принимается. жаль, что

CHill60

Существует ссылка на улучшение вопроса (видимая, если вы нажмете на свой вопрос) - таким образом, вы можете сохранить форматирование кода. Я сделал это для тебя

CHill60

Кроме того - если вам нужно поместить символы в комментарии в будущем, попробуйте использовать html-разметку для символа, например & l t точка с запятой(без пробелов)-это <

2 Ответов

Рейтинг:
6

Maciej Los

Другой способ-использовать операторы (больше или равно) и (меньше). Видеть:

DECLARE @startts DATETIME = CONVERT(DATETIME, CONVERT(DATE, GETDATE()))
DECLARE @endts DATETIME = DATEADD(HH, 24, @startts) 

;WITH CTE AS
(
	--initial part
	SELECT 1 tsid, @startts AS tsstart, DATEADD(MINUTE, 15, @startts) tsend 
	--recursive part
	UNION ALL
	SELECT tsid +1, tsend, DATEADD(MINUTE, 15, tsend) 
	FROM CTE 
	WHERE DATEADD(MINUTE, 15, tsend)  <= @endts
)
SELECT *
FROM CTE slots INNER JOIN YourTable data ON data.SomeDateTimeField >= tsstart AND data.SomeDateTimeField < tsend 


Member 14816845

Спасибо тебе за ритуальное решение. Это мне очень помогает.

Maciej Los

Всегда пожалуйста.

Рейтинг:
19

CHill60

Во - первых, в вашем CTE вы возвращаете результат VARCHAR как Time_Slot-и, вероятно, не тот результат, который вы ожидали.. временной интервал 1-это "020-04-29 00:00"

Используйте возвращаемое значение DATETIME, и я бы немного упростил ваш рекурсивный CTE, чтобы сделать его более понятным. Например

;With temp
As
(
   SELECT 1 as Time_ID, DATEADD(day, DATEDIFF(day,0,GETDATE()),0)  as Time_Slot
   UNION ALL
   SELECT Time_ID+1 ,DATEADD(minute, 15, Time_Slot)
   FROM temp
   WHERE Time_ID < 24 * 60 / 15	-- 1 day in 15 minute slots
)
Ваша следующая проблема будет заключаться в том, чтобы найти время из вашего основного стола в каждом из этих слотов. Время в таблице данных должно находиться между двумя датами. У вас уже есть 1 из них - когда слот начинается - вы также должны захватить, когда он заканчивается - за 1 секунду до начала следующего. Это достаточно просто в вашем существующем CTE - например
;With temp
As
(
   SELECT 1 as Time_ID, DATEADD(day, DATEDIFF(day,0,GETDATE()),0)  as Time_Slot, DATEADD(second, (15 * 60) -1, DATEADD(day, DATEDIFF(day,0,GETDATE()),0)) as EndSlot
   UNION ALL
   SELECT Time_ID+1 , DATEADD(minute, 15, Time_Slot), DATEADD(second, (15 * 60) -1, DATEADD(minute, 15, Time_Slot))
   FROM temp
   WHERE Time_ID < 24 * 60 / 15	-- 1 day in 15 minute slots
)
Затем вы можете использовать обе эти даты в запросе например
select * 
from #test A
inner join temp B on A.dt BETWEEN B.Time_Slot AND B.EndSlot
Вот некоторая документация по оператору BETWEEN MySQL между оператором объясняется практическими примерами[^]

Предостережение: я сделал все это в T-SQL для SQL Server. Я пытался убедиться, что он совместим с MySQL, но, возможно, я пропустил тонкую разницу!


Maciej Los

5ed!

CHill60

Спасибо!