У меня есть (рабочий) запрос, который фильтрует таблицу на основе количества заданного поля, сгруппированного другим в той же таблице, но он не чувствует себя оптимизированным.
baseTable
code,id,event
55d718,ABAjH0j7yZmVBMhdDf4ab5,eventA
55d718,ABAjH0j7yZmVBMhdDf4ab5,eventB
55d718,ABAjH0j7yZmVBMhdDf4ab5,eventA
55d718,ABAjH0ggMvi-k5z8pbyR8_,eventA
98b1de,ABAjH0gkRy7s1enuFYGgzf,eventC
...
То, что я - концептуально - это "черный список" id
, используемый для фильтрации baseTable
: любая строка, содержащая id
, содержащаяся в черный список должен быть отфильтрован. Правило для внесения в черный список: число идентификаторов больше 1 для данного кода и заданное c событие eventA
.
Expected result
code, eventA (count), eventB (count), eventC (count)
55d718, 352, 18, 12
98b1de, 846, 78, 65
Ожидаемым результатом является подсчет каждого события для всех различных кодов, но любой id
, который появляется более 1 раза для данного code
и event = eventA
(в частности, eventA
, а не остальные) должны быть полностью удалены из конечного результата. В примере данные ABAjH0j7yZmVBMhdDf4ab5
имеют более 1 строки для кода 55d718
и eventA
, поэтому filterTable
не должно содержать одну строку с id = ABAjH0j7yZmVBMhdDf4ab5
(даже для других событий).
Рабочий (но неоптимизированный) запрос:
WITH
baseTable as (select
REGEXP_EXTRACT(cs_uri,r'code=([^&]*)') AS code,
REGEXP_EXTRACT(cs_uri,r'id=([^&]*)') AS id,
REGEXP_EXTRACT(cs_uri,r'event=([^&]*)') AS event
from `my-project.raw_data`
),
filteredTable as (SELECT *
FROM baseTable
where id = 'abcd' AND id NOT IN (
SELECT
id
from baseTable where (event = 'eventA') and code = 'abcd'
group by id
having count(id ) > 1
)
)
SELECT eventA , eventB from
(Select count(id) from filteredTable where event = 'eventA') as eventA,
(Select count(id) from filteredTable where event = 'eventB') as eventB
... other queries on filteredTable
Каждый добавляемый мной запрос filteredTable
добавляет к обработанным данным размер baseTable
, есть ли лучший способ?
Лучшим (я думаю) запросом было бы установить having code='XXXX'
непосредственно в baseTable
, поскольку мне не нужно запрашивать несколько кодов одновременно, но проблема в том, что я не могу сделайте это без group by id, code, event
, что делает невозможным правильную настройку черного списка (поскольку тогда невозможно получить счет для eventA
).