Выбор строк до определенного значения в разделах - PullRequest
1 голос
/ 08 ноября 2019

Я пытаюсь выбрать строки, пока не будет достигнут определенный тип события. Например, ниже мы хотим выбрать все строки, содержащие event1, пока не достигнем строки, содержащей event2, разделенной по id

Ввод:

| id     | type   | sequence |
|--------|--------|----------|
| abc123 | event1 | 1        |
| abc123 | event1 | 2        |
| abc123 | event1 | 3        |
| abc123 | event2 | 4        |
| abc123 | event1 | 5        |
| abc123 | event1 | 6        |
| def456 | event1 | 4        |
| def456 | event1 | 5        |
| def456 | event2 | 6        |
| def456 | event1 | 7        |
| ghi789 | event2 | 1        |
| ghi789 | event1 | 2        |
| ghi789 | event1 | 3        |

Что даст следующий результат.

Вывод:

| id     | type   | sequence |
|--------|--------|----------|
| abc123 | event1 | 1        |
| abc123 | event1 | 2        |
| abc123 | event1 | 3        |
| abc123 | event2 | 4        |
| def456 | event1 | 4        |
| def456 | event1 | 5        |
| def456 | event2 | 6        |
| ghi789 | event2 | 1        |

Мне надоело ранжировать данные row_number() over(partition by id, type order by sequence) rank_, чтобы различить данные, которые я хочу выбрать, но не могу выполнить следующий шаг в действительном определениикритерии выбора. По сути, я хочу определить условие, которое говорит:

select * from table where seq=<{integer appearing in sequence column when row features event2 in type column, partitioned by id}

Ответы [ 2 ]

1 голос
/ 08 ноября 2019

Вы можете использовать оконные функции, чтобы получить минимальную последовательность для «event2»:

select t.*
from (select t.*,
             min(case when type = 'event2' then sequence end) over (partition by id) as event2_sequence
      from t
     ) t
where event2_sequence is null or
      sequence <= event2_sequence;

Примечание: я предполагаю, что если нет «event2», то вам нужны все строки. Кроме того, если у вас есть другие события, вы можете захотеть отфильтровать их до «event1» и «event2».

В качестве примечания вы можете использовать коррелированный подзапрос:

select t.*
from t
where t.sequence <= (select min(t2.sequence)
                     from t t2
                     where t2.id = t.id and t2.type = 'event2'
                    );

Примечание: это не вернет идентификаторы, которые не имеют "event2", хотя вы можете обработать это как:

select t.*
from t
where t.sequence <= (select coalesce(min(case when t2.type = 'event2' then t2.sequence end),
                                     max(t2.sequence)
                                    )
                     from t t2
                     where t2.id = t.id
                    );
0 голосов
/ 08 ноября 2019

Ниже для BigQuery Standard SQL

#standardSQL
SELECT * EXCEPT(flag) FROM (
  SELECT id, type, sequence, 0 = COUNTIF(type = 'event2') OVER(win) flag
  FROM `project.dataset.table`
  WINDOW win AS (PARTITION BY id ORDER BY sequence ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
)
WHERE flag 

Вы можете протестировать, поиграть с выше, используя примеры данных из вашего вопроса, как в примере ниже

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 'abc123' id, 'event1' type, 1 sequence UNION ALL
  SELECT 'abc123', 'event1', 2 UNION ALL
  SELECT 'abc123', 'event1', 3 UNION ALL
  SELECT 'abc123', 'event2', 4 UNION ALL
  SELECT 'abc123', 'event1', 5 UNION ALL
  SELECT 'abc123', 'event1', 6 UNION ALL
  SELECT 'def456', 'event1', 4 UNION ALL
  SELECT 'def456', 'event1', 5 UNION ALL
  SELECT 'def456', 'event2', 6 UNION ALL
  SELECT 'def456', 'event1', 7 UNION ALL
  SELECT 'ghi789', 'event2', 1 UNION ALL
  SELECT 'ghi789', 'event1', 2 UNION ALL
  SELECT 'ghi789', 'event1', 3 
)
SELECT * EXCEPT(flag) FROM (
  SELECT id, type, sequence, 0 = COUNTIF(type = 'event2') OVER(win) flag
  FROM `project.dataset.table`
  WINDOW win AS (PARTITION BY id ORDER BY sequence ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
)
WHERE flag 
-- ORDER BY id, sequence   

с выводом

Row id      type    sequence     
1   abc123  event1  1    
2   abc123  event1  2    
3   abc123  event1  3    
4   abc123  event2  4    
5   def456  event1  4    
6   def456  event1  5    
7   def456  event2  6    
8   ghi789  event2  1    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...