BigQuery SQL Query Optimization - PullRequest
       12

BigQuery SQL Query Optimization

0 голосов
/ 21 февраля 2019

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

Набор данных BigQuery, с которым я работаю, прибывает изHubspot.Это синхронизировано Стичем.(Для тех, кто не знаком с BigQuery, большинство интеграций только для добавления, поэтому мне нужно отфильтровать старые копии через строку ROW_NUMBER() OVER, которую вы увидите ниже, поэтому она существует. Похоже, это стандартный способ справиться с этой причудой.)

Складка с таблицей companies - это каждое отдельное поле, кроме двух идентификаторов, типа RECORD.(Смотрите скриншот внизу для примера).Служит для хранения истории изменений значений полей.К сожалению, они, кажется, не в каком-либо порядке, поэтому оборачивание полей - например, properties.first_conversion_event_name - в MIN() или MAX() и группировка по формуле компании не работает.

Это то, чем я закончил (последний запрос намного длиннее; я не включил все поля в приведенный ниже пример):

WITH companies AS (
SELECT
    o.companyid as companyid,
    ARRAY_AGG(STRUCT(o.properties.name.value, o.properties.name.timestamp) ORDER BY o.properties.name.timestamp DESC)[SAFE_OFFSET(0)] as name,
    ARRAY_AGG(STRUCT(o.properties.industry.value, o.properties.industry.timestamp) ORDER BY o.properties.industry.timestamp DESC)[SAFE_OFFSET(0)] as industry,
    ARRAY_AGG(STRUCT(o.properties.lifecyclestage.value, o.properties.lifecyclestage.timestamp) ORDER BY o.properties.lifecyclestage.timestamp DESC)[SAFE_OFFSET(0)] as lifecyclestage
FROM (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY o.companyid ORDER BY o._sdc_batched_at DESC) as seqnum
  FROM `project.hubspot.companies` o) o
WHERE seqnum = 1
GROUP BY companyid)

SELECT
  companyid,
  name.value as name,
  industry.value as industry,
  lifecyclestage.value as lifecyclestage
FROM companies

Предложение WITHвверху - избавиться от лишних полей, которые включает в себя ARRAY_AGG(STRUCT()).Для каждого поля у меня будет два столбца - [field].value и [field].timestamp - и мне нужен только один [field].value.

Заранее спасибо!

Скриншот схемы

1 Ответ

0 голосов
/ 21 февраля 2019

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

На основе представленной вами схемыи предполагая, что ваш запрос действительно возвращает то, что вы ожидаете - ниже «оптимизированной» версии должен возвращаться тот же результат

#standardSQL
WITH companies AS (
  SELECT
      o.companyid AS companyid,
      STRUCT(o.properties.name.value, o.properties.name.timestamp) AS name,
      STRUCT(o.properties.industry.value, o.properties.industry.timestamp) AS industry,
      STRUCT(o.properties.lifecyclestage.value, o.properties.lifecyclestage.timestamp) AS lifecyclestage
  FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY o.companyid ORDER BY o._sdc_batched_at DESC) AS seqnum
    FROM `project.hubspot.companies` o
  ) o
  WHERE seqnum = 1
)
SELECT
  companyid,
  name.value AS name,
  industry.value AS industry,
  lifecyclestage.value AS lifecyclestage
FROM companies   

Как вы можете видеть, я просто удалил GROUP BY companyid, потому что у вас уже есть только одна запись / строка на каждую компаниюпосле применения WHERE seqnum = 1, поэтому нет никакой причины группировать только одну строку для каждой компании.По той же самой причине я удалил ARRAY_AGG( ORDER BY)[SAFE_OFFSET(0)] - он просто агрегировал одну структуру, а затем извлек этот элемент из массива - поэтому нет необходимости делать это

...