2016-01-12 8 views
3

У меня есть столбец категории со строкой, содержащей поля подкатегорий в переменных положениях, разделенных символом «|». Расположение каждой подкатегории зависит от количества элементов в строке. Например:Условные сгенерированные сгенерированные транзакции Bigquery

category subcat1 subcat2 subcat3 
a|b|c  b   c   a 
x|y|a|b  b   null  a 

Таким образом, чтобы решить для одной категории, у меня есть:

SELECT 
    a.category AS category, 
    case 
    WHEN COUNT(SPLIT(a.category, "|")) = 4 then nth(4, SPLIT(a.category, "|")) 
    WHEN COUNT(SPLIT(a.category, "|")) = 3 then nth(2, SPLIT(a.category, "|")) 
    WHEN COUNT(SPLIT(a.category, "|")) = 2 then nth(2, SPLIT(a.category, "|")) 
    else null 
    end as subcat1, 
    --nth(2, SPLIT(a.category, "|")) as x  --uncomment for success. see below 
FROM 
    [interim_groups.articles_unique] as a 

Запуск этого терпит неудачу с:

SELECT clause has mix of aggregations 'subcat1' and fields 'category' without GROUP BY clause 

Теперь я не хочу, пункт group by и он не имеет смысла иметь его, но если я его включаю, он начинает жаловаться на скользящие скопления, которые, кажется, идут в неправильном направлении.

То же самое происходит, если я использую инструкцию if вместо инструкции case.

Теперь вот странный бит. Если у меня есть прокомментированная строка (или, альтернативно, last(SPLIT(a.category, "|")) as x) в моем запросе, запрос проходит безупречно.

Это ошибка? Мой запрос выглядит правдоподобно, и наличие лишнего столбца в моем запросе каким-то образом делает его пропуск странным.
Есть ли лучший способ исправить это, чем просто оставить ненужный столбец для стабилизации запроса?

ответ

5

В запросе отсутствует ключевое слово 'WITHIN RECORD'.

SELECT 
    a.category AS category, 
    case 
    WHEN COUNT(SPLIT(a.category, "|")) = 4 then nth(4, SPLIT(a.category, "|")) 
    WHEN COUNT(SPLIT(a.category, "|")) = 3 then nth(2, SPLIT(a.category, "|")) 
    WHEN COUNT(SPLIT(a.category, "|")) = 2 then nth(2, SPLIT(a.category, "|")) 
    else null 
    end WITHIN RECORD as subcat1 , 
FROM (SELECT category FROM 
    (SELECT 'a|b|c' category), (SELECT 'a|b' category), (SELECT 'a|b|c|d' category)) a 

Смотрите документацию для ТЕЧЕНИЕ:

Внутри- ключевое слово конкретно работает с агрегатными функциями агрегировать через детей и неоднократных полей в записях и вложенных полей. Когда вы указываете ключевое слово WITHIN, вам нужно указать область, по которой вы хотите скопировать. WITHIN RECORD: Совокупность данных в повторяющихся значениях в записи.

https://cloud.google.com/bigquery/docs/data#within

2

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

Meantime ниже версии с использованием Regular expression functions - это немного более мощный для потенциально более сложной scenarious

SELECT 
    a.category AS category, 
    CASE 
    WHEN LENGTH(REGEXP_REPLACE(a.category, r"[^|]", "")) = 4 
      THEN REGEXP_EXTRACT(a.category, r'\|\w+\|\w+\|\w+\|(\w+)') 
    WHEN LENGTH(REGEXP_REPLACE(a.category, r"[^|]", "")) = 3 
      THEN REGEXP_EXTRACT(a.category, r'\|\w+\|\w+\|(\w+)') 
    WHEN LENGTH(REGEXP_REPLACE(a.category, r"[^|]", "")) = 2 
      THEN REGEXP_EXTRACT(a.category, r'\|\w+\|(\w+)') 
    ELSE NULL 
    END AS subcat1 
FROM your_table a 

Нет группировки, нет ненужного столбца, как задано в вопросе!

+0

Отличное решение! Но см. Альтернативный ответ о том, как «WITHIN» исправляет проблему. –

+0

полностью согласен! ВХОД - это путь сюда. Голосование за это! –

+0

Мой запрос на самом деле начался с регулярного выражения, но регулярное выражение получило беспорядок, потому что не все строки между '|' были захвачены как целое слово (например, перенос) – Roman

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