REGEXP заменить пустым

Я изучаю базу данных с помощью 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

Я попробовал несколько других итераций, но все они возвращают ошибку. Любые предложения о том, как изменить запрос?

Какая ссылка на документ, на который вы ссылаетесь? Является ли ваш код копией/вставкой в ​​этом вопросе StackOverflow? Не могли бы вы ввести " (двойную кавычку) вместо '' (две одинарные кавычки)....

Kolban 13.06.2024 03:25

Да, в основном копирование и вставка. Согласен, это похоже на причину, но я попробовал два сингла, и это все равно не помогло. Если я заменю двойные кавычки одинарными, я получу другую ошибку: нет соответствующей подписи для функции REGEXP_REPLACE для типов аргументов: ARRAY<STRING>, STRING, STRING. Это документ: blog.gdeltproject.org/google-bigquery-gkg -2-0-образец-запросов

Celeste 13.06.2024 05:15

Привет @celeste, не могли бы вы поделиться каким-нибудь демо-набором данных?

Sourav Dutta 13.06.2024 12:48

Переход на одинарные кавычки «кажется» правильным ответом, а двойные кавычки были ОРИГИНАЛЬНОЙ проблемой. Я бы предложил переключиться на две одинарные кавычки... и СЕЙЧАС у нас есть НОВАЯ головоломка (но правильная, которую нужно решить). Как предлагал @Sourav, теперь нам нужно увидеть схему и данные... особенно столбца с именем «столбец1».

Kolban 13.06.2024 14:35

После разделения столбец1 становится массивом, как следует из ошибки. Как вы хотите обрабатывать этот массив? Хотите заменить каждый элемент массива?

Sabri Karagönen 13.06.2024 18:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
68
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.

Решение бизнес-проблемы, а не технической проблемы

Похоже, вы хотите извлечь значения из значений «тега» до запятой (но не включая ее), затем вы можете извлечь их следующим образом.

  1. Очистите данные, которые нам не нужны, с начала и конца, т. е. что угодно. перед первым значением «тега» и разделителями каналов.
  2. Разделите данные точкой с запятой, чтобы мы работали только со строками «тег...». Он рассматривается как массив, поэтому нам нужно преобразовать его обратно в строку.
  3. Найдите запятую в каждой строке и удалите ее и все, что следует за ней.
  4. Группировка по ценностям человека.

Следующий код разбит на части, поэтому я могу объяснить его по ходу дела. Вы можете консолидировать его по мере необходимости, но он будет не таким читабельным.

--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 возвращает 6
  • SUBSTRING("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() не может быть отрицательным. Обходной путь заключался в том, чтобы просто включить запятую, поскольку она все еще служила цели, но просто визуально была менее привлекательной.

Celeste 19.06.2024 04:51

Отлично, рад, что смог вам помочь.

mjruttenberg 19.06.2024 14:14

Другие вопросы по теме