SQL объединить несколько записей в 1 строку по дате

#sql-server #tsql

#sql-сервер #tsql

Вопрос:

Я хотел бы найти время, прошедшее между последовательными (в соответствии с полем даты) записями в таблице журнала…

Например,

введите описание изображения здесь

Это записи журнала для процессов, которые я запускаю каждый день. Я хочу создать отчет с различными полями, такими как дата начала и окончания, истекшие минуты и т.д., Но чтобы упростить «суть» моей проблемы, я думаю, мне нужно выяснить, как получить эти записи начала и окончания (отмеченные полем комментария) в одну строку, которая будет представлять 1 запуск процесса. run. Я пробовал сводную таблицу, но у меня не получилось заставить это работать, поскольку я не мог использовать «Порядок по дате» с Pivot, что, я думаю, мне нужно для того, чтобы агрегат «Max» был полезен. Я пробовал группировать…Я почти заставил его работать с самосоединением, используя «Row_Number ()» и присоединяя Row_Number() к RowNumber 1 (поскольку время каждого запуска уменьшается на 1 строку по сравнению с последним запуском ..)

но затем я нашел несколько записей, где это было не так. Я полагаю, что эта базовая задача выполнялась много раз, но я еще не нашел своего решения.

Как я могу просто выполнить каждый запуск процесса (определяемый датой «начала» и, предположительно, ближайшей датой «окончания») и объединить их в одну строку, чтобы я мог выполнять дополнительные агрегаты?

Комментарии:

1. Пометьте свой вопрос базой данных, которую вы используете. Кроме того, вы всегда знаете, что значения чередуются?

2. Я не могу пометить свою базу данных, поскольку она не является общедоступной. Но я бы подумал, что начало и конец следуют показанному шаблону (начало, затем конец), но я бы подумал, что мое решение путем объединения RowNumber() и RowNumber () 1 сработало бы. Но я видел некоторые редкие случаи, когда даты начала были последовательными (без промежуточной даты окончания)… Я полагаю, что если в моих процессах есть ошибки, то даты окончания не всегда будут регистрироваться …?

3. Ваша база данных является частной? Вы имеете в виду, что используете полностью пользовательскую СУБД? Это необычно. Большинство людей используют что-то вроде SQL Server, MySQL, Oracle, одно из них. Это то, что Гордон имел в виду, говоря «пометить вашу базу данных». Вам не нужно раскрывать нерелевантные подробности обо всех ваших таблицах и данных, но вам нужно сообщить нам, какой продукт вы используете. Синтаксис и функции, доступные для ответа, могут различаться у разных поставщиков.

4. О, хорошо. Это SQL (T-SQL). Позвольте мне выяснить, как пометить SQL. Извините, я думал, что я это сделал!

Ответ №1:

Если «следующая» запись всегда является конечной записью, вы можете сделать:

 select t.*
from (select t.*,
             lead(log_date) over (order by log_date) as end_log_date
      from t
     ) t
where comment = 'Start tf_crediting : FULL';
  

Если вам нужна следующая конечная дата, то совокупный условный минимум делает то, что вы хотите:

 select t.*
from (select t.*,
             min(case when comment = 'end Crediting' then log_date end) over (order by log_date desc) as end_log_date
      from t
     ) t
where comment = 'Start tf_crediting : FULL';
  

Комментарии:

1. Похоже, это делает работу, спасибо! … Я должен еще немного изучить этот синтаксис с помощью «Over». Я использовал его только с RowNumber() и partition, но я не знаю, действительно ли я понял использование самого «over». Это может помочь мне и с другими проблемами 🙂