2015-05-15 2 views
3

Использование SPLIT() & NTH(), я разделяю строковое значение и беря 2-ю подстроку в качестве результата. Затем я хочу сгруппировать по этому результату. Однако, когда я использую SPLIT() в сочетании с GROUP BY, она продолжает давать ошибку:BigQuery SPLIT() и группировка по результату

Error: (L1:55): Cannot group by an aggregate 

Результатом является строка, так почему это не возможно сгруппировать по нему?

Например, это работает и возвращает правильную строку:

SELECT NTH(2,SPLIT('FIRST-SECOND','-')) as second_part FROM [FOO.bar] limit 10 

enter image description here

Но группировка на результат не работает:

SELECT NTH(2,SPLIT('FIRST-SECOND','-')) as second_part FROM [FOO.bar] GROUP BY second_part limit 10 

enter image description here

ответ

5

Мои лучше всего предположить, что вы можете получить equiv результат, используя подзапрос. Что-то вроде:

SELECT * FROM (Select NTH(2,SPLIT('FIRST-SECOND','-')) as second_part FROM [FOO.bar] limit 10) GROUP BY second_part 

Система возвращает NTH в совокупности внутренне я думаю

+0

Это работает. Но это действительно не обязательно. –

4

Если всегда есть только два значения разделенные вертикальной, то простой подход будет использовать REGEXP_EXTRACT:

SELECT REGEXP_EXTRACT('FIRST-SECOND','-(.*)') as second_part 
from [FOO.bar] 
GROUP BY second_part 
limit 10 
1

Мне нравится ответ Дэвида - иногда расщепление может немного усложниться с помощью RegEx. Извлекая первый вариант из команды split, GROUPING BY является очень распространенной операцией. Как обычно я делаю это в BigQuery, используйте REGEXP_EXTRACT следующим образом:

В этом простом примере столбец «splitme» разделен на трубы (|).

SELECT REGEXP_EXTRACT(splitme, r'(?U)^(.*)\|') AS title, COUNT(*) as c 
FROM [my_table] 
GROUP BY title; 

Это означает, извлечь строку с начала «splitme» на первое вхождение трубы (|). «(? U)» - это флаг «un-greedy» match в синтаксисе двигателя re2 RegEx. Без этого флага, если имеется несколько значений с разделителями по каналам, этот RegEx будет соответствовать всем до последнего канала.

+0

Небольшая коррекция - для извлечения второго значения (как и в вопросе) должна быть REGEXP_EXTRACT (splitme, r '(? U) ^. * \ | (. *) \ |') ' –

0

В моей практике я обычно использую что-то вроде ниже, где N - количество значений в «списке» для пропуска.

SELECT REGEXP_EXTRACT(string + '|', r'(?U)^(?:.*\|){N}(.*)\|') AS substring 

Так что, если я был бы заинтересован в третье значение в списке, я хотел бы использовать:

SELECT 
    REGEXP_EXTRACT(string + '|', r'(?U)^(?:.*\|){2}(.*)\|') AS substring, 
    COUNT(1) AS weight 
FROM yourtable 
GROUP BY 1 

Более подробную информацию о синтаксисе RE2 here

Смежные вопросы