Извлечь первое появление элемента в столбце A на основе столбца B с использованием SQL

У меня есть следующие данные, и я хотел бы создать результирующий набор, который включает в себя строки, которые являются изменением Item и первым вводом Code == 1 . Обратите внимание, что первый Code видимый после chnage в Item , не всегда должен быть 1 (см. *):

Входные данные:

  Код позиции DateTime
 * 2016-12-02 16:34:00 1 1 
  2016-12-02 16:35:00 1 4
  2016-12-02 16:36:00 1 1
  2016-12-02 16:37:00 1 1
  2016-12-02 16:38:00 1 7
  2016-12-02 16:39:00 1 5
  2016-12-02 16:40:00 1 6
  2016-12-02 16:41:00 2 5
 * 2016-12-02 16:42:00 2 1
  2016-12-02 16:43:00 2 4
  2016-12-02 16:44:00 2 1
  2016-12-02 16:45:00 2 5
  2016-12-02 16:46:00 2 8
  2016-12-02 16:47:00 2 1
  2016-12-02 16:48:00 5 7
  2016-12-02 16:49:00 5 7
 * 2016-12-02 16:50:00 5 1
  2016-12-02 16:51:00 5 1
  2016-12-02 16:52:00 5 4
  2016-12-02 16:53:00 5 3
 * 2016-12-02 16:54:00 1 1
  2016-12-02 16:55:00 1 1
  2016-12-02 16:56:00 1 1
  2016-12-02 16:57:00 1 8
  2016-12-02 16:58:00 1 9
  2016-12-02 16:59:00 1 3
  2016-12-02 17:00:00 1 2
  2016-12-02 17:01:00 1 4

Ожидаемые выходные данные:

  Код позиции DateTime
 * 2016-12-02 16:34:00 1 1 
 * 2016-12-02 16:42:00 2 1
 * 2016-12-02 16:50:00 5 1
 * 2016-12-02 16:54:00 1 1

Я использую SQL Server 2012 Express. Если у кого-то есть рекомендации хорошей ссылки, чтобы изучить эти вещи, это было бы здорово.

Вы можете использовать разницу ROW_NUMBER s, чтобы определить, где значение Item изменилось, а затем еще один ROW_NUMBER , чтобы получить первое вхождение Code = 1 :

 WITH CteGrp AS( SELECT *, grp = ROW_NUMBER() OVER(ORDER BY Datetime) - ROW_NUMBER() OVER(PARTITION BY Item ORDER BY Datetime) FROM #Tbl ), Cte AS( SELECT *, rn = ROW_NUMBER() OVER(PARTITION BY Item, grp ORDER BY Code, Datetime) FROM CteGrp ) SELECT Datetime, Item, Code FROM Cte WHERE rn = 1 ORDER BY Datetime; 

ОНЛАЙН-ДЕМО


Первый CTE является распространенным решением для группировки островов сопредельных дат. Вот статья Джеффа Модена для объяснения:

  • Групповые острова сопредельных дат (SQL Spackle)
 WITH cte AS ( SELECT [DateTime] , Item , Code , ROW_NUMBER() OVER (PARTITION BY Item ORDER BY [DateTime]) AS RowNum ) SELECT [DateTime] , Item , Code FROM cte WHERE RowNum = 1 AND Code = 1; 

Попробуй это

 select min( dateTime) dateTime, item, code from ( select dateTime, item, code from theTableName where code = 1 ) code_1s group by item, code 

РЕДАКТИРОВАТЬ

Чтобы получить каждый экземпляр элемента, в котором была запущена новая последовательность, а code = 1 – это флаг для экземпляра новой последовательности … это простой оператор select с предложением where.

  select dateTime, item, code from theTableName where code = 1 
Interesting Posts

Расчет общего числа

фильтрация записей с левым внешним соединением в sql

Почему VALUES (CONVERT (XML, '…')) намного медленнее, чем VALUES (@xml)?

Тонкий запрос счетчика T-SQL … может ли он быть оптимизирован с помощью EXISTS или чего-то еще?

IF Else в функции

Журнал удаленных хранимых процедур SQL Server 2008

Более быстрый способ получить SQL-совместимую строку из Guid

SQL: получить последнюю (un) подписку из таблицы

Как преобразовать функцию SQL getdate () в строку в формате dd / mm / yyyy?

Как ограничить просмотр пользователями системных таблиц / представлений

SSIS Выполнение задачи пакета на SQL Server 2016

Чтобы рассчитать Дату до двух рабочих дней, если не рабочий день, тогда увеличьте

Хранимая процедура SQL Server, которая возвращает логическую, если существует таблица, реализация c #

Доступ к данным из другой базы данных в хранимой процедуре

SQL Server: значение split на основе разделителя и совпадение во время выполнения

Давайте будем гением компьютера.