SQL: выберите самое последнее последовательно различающееся значение с группировкой - PullRequest
0 голосов
/ 03 июня 2019

У меня возникли проблемы при написании запроса, в котором было бы выбрано последнее «новое» последовательно различающееся значение (назовем этот столбец Col A), сгруппированное на основе другого столбца (Col B).Поскольку это немного двусмысленно / запутанно, вот пример для объяснения (предположим, что номер строки указывает на последовательность внутри групп; в моем выпуске строки упорядочены по дате):

|--------|-------|-------|
| RowNum | Col A | Col B |
|--------|-------|-------|
| 1      | A     | A     |
| 2      | B     | A     |
| 3      | C     | A     |
| 4      | B     | B     |
| 5      | A     | B     |
| 6      | B     | B     |

Выберет:

| 3      | C     | A     |
| 6      | B     | B     |

Обратите внимание, что хотя B также появляется в строке 4, тот факт, что строка 5 содержит A, означает, что B в строке 6 последовательно различается.Но если бы таблица выглядела так:

|--------|-------|-------|
| RowNum | Col A | Col B |
|--------|-------|-------|
| 1      | A     | A     |
| 2      | B     | A     |
| 3      | C     | A     |
| 4      | B     | B     |
| 5      | A     | B     |
| 6      | A     | B     | <--

Тогда мы бы хотели выбрать:

| 3      | C     | A     |
| 5      | A     | B     |

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

Я пытался решить эту проблему, вычисляя минимальные / максимальные номера строк, где появляется каждое значение Col A.Этот расчет (с использованием второй примерной таблицы) приведет к такому результату:

|--------|--------|--------|--------|
| ColA   | ColB   | MinRow | MaxRow |
|--------|--------|--------|--------|
| A      | A      | 1      | 1      |
| B      | A      | 2      | 2      |
| C      | A      | 3      | 3      | 
| A      | B      | 5      | 6      |
| B      | B      | 4      | 4      | 

Решение, возникшее в соответствующей публикации ( SQL: выбрать строку с последним новым последовательным отличительным значением )пошел по тому же пути, по сути, взяв самый последний RowNum, который отличается от последнего ColA, и затем выбирает следующий ряд.Тем не менее, в этом вопросе я не учел необходимость работы запроса для нескольких групп, а значит, и нового поста.

Буду признателен за любую помощь в решении этой проблемы, если это вообще возможно сделать в SQL.Я использую SQL 2008 SP4.

1 Ответ

0 голосов
/ 03 июня 2019

Хммм. , , Один из способов - получить последнее значение. Затем выберите все последние строки с этим значением и агрегат:

select min(rownum), colA, colB
from (select t.*,
             first_value(colA) over (partition by colB order by rownum desc) as last_colA
      from t
     ) t
where rownum > all (select t2.rownum
                    from t t2
                    where t2.colB = t.colB and t2.colA <> t.last_colA
                   )
group by colA, colB;

Или без агрегации:

select t.*
from (select t.*,
             first_value(colA) over (partition by colB order by rownum desc) as last_colA,
             lag(colA) over (partition by colB order by rownum) as prev_clA
      from t
     ) t
where rownum > all (select t2.rownum
                    from t t2
                    where t2.colB = t.colB and t2.colA <> t.last_colA
                   ) and
      (prev_colA is null or prev_colA <> colA);

Но в SQL Server 2008 давайте рассмотрим это как проблему пробелов и островков:

select t.*
from (select t.*,
             min(rownum) over (partition by colB, colA, (seqnum_b - seqnum_ab) ) as min_rownum_group,
             max(rownum) over (partition by colB, colA, (seqnum_b - seqnum_ab) ) as max_rownum_group
      from (select t.*,
                   row_number() over (partition by colB order by rownum) as seqnum_b,
                   row_number() over (partition by colB, colA order by rownum) as seqnum_ab,
                   max(rownum) over (partition by colB order by rownum) as max_rownum
            from t
           ) t
     ) t
where rownum = min_rownum_group and  -- first row in the group defined by adjacent colA, colB
      max_rownum_group = max_rownum  -- last group for each colB;

Это идентифицирует каждую из групп, используя разницу номеров строк. Он рассчитывает максимальный rownum для группы и в целом в данных. Это то же самое для последней группы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...