Я изучаю базу данных с помощью BigQuery и следую относительно старому документу, который возвращает ошибку в приведенном ниже запросе. Записи в рассматриваемом столбце имеют вид |столбец1| |:--- | |тег1,3125;тег2,024|
Где цифры после запятой являются нерелевантными смещениями символов. Код пытается 1) разделить строки точкой с запятой и 2) удалить запятую и смещение символов и просто сохранить имя тега. Предлагаемое выражение приведено ниже, но оно возвращает ошибку: «Синтаксическая ошибка: незакрытый строковый литерал в [3:52]»
SELECT person, COUNT(*) as count
FROM (
select REGEXP_REPLACE(SPLIT(column1,';'), r',.*', ") person
from 'db_name')
group by person
ORDER BY 2 DESC
Я попробовал несколько других итераций, но все они возвращают ошибку. Любые предложения о том, как изменить запрос?
Да, в основном копирование и вставка. Согласен, это похоже на причину, но я попробовал два сингла, и это все равно не помогло. Если я заменю двойные кавычки одинарными, я получу другую ошибку: нет соответствующей подписи для функции REGEXP_REPLACE для типов аргументов: ARRAY<STRING>, STRING, STRING. Это документ: blog.gdeltproject.org/google-bigquery-gkg -2-0-образец-запросов
Привет @celeste, не могли бы вы поделиться каким-нибудь демо-набором данных?
Переход на одинарные кавычки «кажется» правильным ответом, а двойные кавычки были ОРИГИНАЛЬНОЙ проблемой. Я бы предложил переключиться на две одинарные кавычки... и СЕЙЧАС у нас есть НОВАЯ головоломка (но правильная, которую нужно решить). Как предлагал @Sourav, теперь нам нужно увидеть схему и данные... особенно столбца с именем «столбец1».
После разделения столбец1 становится массивом, как следует из ошибки. Как вы хотите обрабатывать этот массив? Хотите заменить каждый элемент массива?





Исправление сообщенной ошибки
Я не уверен, что SPLIT с REGEX_REPLACE — это правильный путь. Когда я исправил двойную кавычку на две двойные кавычки, я получил ошибку, связанную с тем, что SPLIT является массивом, но затем вы пытаетесь работать с ним как со строкой.
with db_name AS (
SELECT
"|column1| |:--- | |tag1,3125;tag2,024|" AS column1
)
select REGEXP_REPLACE(SPLIT(column1,';'), r',.*',"") person
from db_name
Ошибка:
No matching signature for function REGEXP_REPLACE for argument types: ARRAY<STRING>, STRING, STRING. Supported signatures: REGEXP_REPLACE(STRING, STRING, STRING); REGEXP_REPLACE(BYTES, BYTES, BYTES) at [6:8]
Таким образом, даже если вы преодолеете описанную ошибку, вы все равно не сможете пользоваться REPLACE.
Решение бизнес-проблемы, а не технической проблемы
Похоже, вы хотите извлечь значения из значений «тега» до запятой (но не включая ее), затем вы можете извлечь их следующим образом.
Следующий код разбит на части, поэтому я могу объяснить его по ходу дела. Вы можете консолидировать его по мере необходимости, но он будет не таким читабельным.
--specify the supplied string example in a CTE
WITH
tmp AS (
SELECT
"|column1| |:--- | |tag1,3125;tag2,024|" AS person
),
Затем мы удаляем ложные данные до первого значения «тега» и удаляем все оставшиеся символы вертикальной черты (|).
Это меняет |column1| |:--- | |tag1,3125;tag2,024| на tag1,3125;tag2,024|, а затем на tag1,3125;tag2,024 следующим образом:
tmp2 AS (
SELECT
REPLACE(SUBSTRING(person,STRPOS(person,"tag"),LENGTH(person)),"|","") AS person
FROM tmp
),
Теперь мы разделяем значение точки с запятой на строки, чтобы создать массив значений тега....
tmp3 AS (
SELECT
SPLIT(person,";") AS person
FROM tmp2
),
Это дает нам массив
tag1,3125
tag2,024
Затем UNNEST преобразует массив в строки строк, чтобы мы могли ими манипулировать дальше.
Найдите индексную позицию запятой и переместите начало строки до этой индексной позиции, но нам придется вернуться на 1 символ назад.
например
STRPOS("tag123,xyz", ",") возвращает 7, поскольку запятая находится в индексной позиции 7.STRPOS("tag123,xyz", ",")-1 возвращает 6SUBSTRING("tag123,xyz",1,STRPOS("tag123,xyz", ",") возвращает позиции индекса 1–7, т. е. tag123,SUBSTRING("tag123,xyz",1,STRPOS("tag123,xyz", ",")-1) возвращает позиции индекса 1–6, т. е. tag123 tmp4 AS (
SELECT
SUBSTRING(u,1,STRPOS(u,",")-1) AS person
FROM tmp3,
UNNEST(person) AS u
)
Это дает нам строковые значения
tag1
tag2
Наконец, вы можете сгруппировать по личным ценностям:
SELECT person, COUNT(*) AS cnt
FROM tmp4
GROUP by 1
ORDER by 2 DESC
Очень полезно, это помогло мне пройти большую часть пути. Предыдущая часть удаления трубопроводов не была необходима для моего варианта использования (это была проблема с форматированием в том, как я поставил вопрос). Единственная часть, которая не работала, это ПОДСТРОКА. Я получил ошибку: Третий аргумент в SUBSTR() не может быть отрицательным. Обходной путь заключался в том, чтобы просто включить запятую, поскольку она все еще служила цели, но просто визуально была менее привлекательной.
Отлично, рад, что смог вам помочь.
Какая ссылка на документ, на который вы ссылаетесь? Является ли ваш код копией/вставкой в этом вопросе StackOverflow? Не могли бы вы ввести " (двойную кавычку) вместо '' (две одинарные кавычки)....