#sql-server-2005 #tsql
#sql-server-2005 #tsql
Вопрос:
Я довольно новичок в программировании баз данных, и мне нужна помощь в написании того, что кажется сложным запросом t-sql.
В нашей базе данных хранятся временные данные вместе с различными уровнями, записанными в то время. Типичное измерение длится недели или месяцы. Мне нужно написать запрос в SqlServer2005 для выявления пробелов в временных данных, чтобы узнать, когда инструмент не обменивался данными. Наш интервал выборки может составлять либо 1 сек, либо .5 сек, но он всегда будет одинаковым при данном измерении (т. Е. Все выборки в измерении будут составлять либо 1, либо .5 выборок в секунду).
В идеале я хотел бы получить список [блок1-начало, блок1-конец] [блок2-начало, блок2-конец] и т. Д
где каждый блок представляет собой единицу последовательного времени в рамках общего измерения.
Существуют ли какие-либо команды в TSQL, которые упростили бы выполнение этого запроса?
Комментарии:
1. Могут ли измерения перекрываться во времени?
2. Смотрите эту статью о Simple Talk
3. Нет, перекрытия во времени не будет.
Ответ №1:
Проверьте это. Поскольку у вас нет перекрывающихся интервалов, вы можете написать простой SQL-запрос для возврата этих результатов. Приведенный ниже SQL создает фиктивную табличную переменную с именем @Events для имитации вашей таблицы измерений. Конечный запрос выдает промежутки, превышающие 1 секунду (настраивается с помощью переменной @MaxIntervalAllowedBetweenEvents).
-- table with dummy data
declare @Events table (
ID int IDENTITY NOT NULL,
StartDate datetime NOT NULL,
EndDate datetime NOT NULL
)
INSERT @Events VALUES ('1/1/2011 1:00am', '1/1/2011 2:00am')
INSERT @Events VALUES ('1/1/2011 2:00am', '1/1/2011 3:00am') -- no gap after previous event
INSERT @Events VALUES ('1/1/2011 3:01am', '1/1/2011 4:00am') -- 1 minute gap
INSERT @Events VALUES ('1/1/2011 4:30am', '1/1/2011 5:00am') -- 30 minute gap
-- this variable defines the maximum interval allowed between events
declare @MaxIntervalAllowedBetweenEvents int
set @MaxIntervalAllowedBetweenEvents = 1 -- # seconds
-- select the gaps between events
SELECT
e1.EndDate,
Min(e2.StartDate) as NextEventStartDate,
DateDiff(s, e1.EndDate, Min(e2.StartDate)) as SecondsBetweenEvents
FROM
@Events as e1
join
-- for each event in e1, get the event that immediately follows it
@Events as e2
on (e1.EndDate <= e2.StartDate)
GROUP BY
e1.EndDate
HAVING
-- filter out events that are too close to each other
(DateDiff(s, e1.EndDate, Min(e2.StartDate)) > @MaxIntervalAllowedBetweenEvents)
ORDER BY
e1.EndDate
Комментарии:
1. довольно приятное решение. Я думал, вам понадобится процедура для этого. Но, похоже, вы можете легко сделать это и в sql.
2. Спасибо! Теперь, если бы даты могли перекрываться, это было бы действительно сложно.
Ответ №2:
Oracle имеет множество отличных аналитических функций для этого.
Я думаю, вам нужно создать курсор из инструкции sql, который упорядочит ваши результаты по дате, времени начала, времени окончания.
Ответ №3:
Таблицу, в которую вводится дата, можно использовать следующим образом, чтобы получить время между входами в систему…
Опустите бит ROW_NUMBER, если в вашей таблице уже есть идентификатор.
{select
Start.ID
,Done.ID
,Start.<Date_Column>
,Done.<Date_Column>
,DATEDIFF(s,Start.<Date_Column>,Done.<Date_Column>) AS InBetween
from
(SELECT
ROW_NUMBER() OVER (ORDER BY <Date_Column>) AS ID
,<Date_Column>
FROM
<Tablename> (NOLOCK)
) START
INNER JOIN (
SELECT
ROW_NUMBER() OVER (ORDER BY <Date_Column>) AS ID
,<Date_Column>
FROM
<Tablename> (NOLOCK)
) DONE ON START.ID 1 = DONE.ID
ORDER BY
DATEDIFF(s,Start.<Date_Column>,Done.<Date_Column>)DESC}