Bigquery, как многофакторный, многофакторный запрос на согласованные измерения - PullRequest
0 голосов
/ 02 ноября 2019

У меня есть три таблицы фактов

Бюджет: категория, товар, бюджетные часы

Факт: категория, товар, дата, фактические часы

Базовый уровень: категория, товар,дата, Прогноз часов

Я хочу написать запрос, чтобы получить сумму бюджетных часов, Фактических часов, Прогноз часов, сгруппированных по категориям, и товаров, отфильтрованных по дате.

Обратите внимание, что три факта имеютНа другом уровне детализации я удалил другое необычное измерение для простоты. В настоящее время я использую этот запрос в Datastudio из BigQuery

with t0 as ( select category, commodity FROM `testing-bi-engine.starschema.budget`
             union distinct
             select category, commodity FROM `testing-bi-engine.starschema.actual`
             union distinct
             select category, commodity FROM `testing-bi-engine.starschema.baseline`)
SELECT t0.category, t0.commodity , sum(t2.actualhours) as actualhours , sum(t3.budgethours) as budgethours , sum(t4.forecast) as forecasthours FROM t0
left outer join
(SELECT category, commodity , sum(actualhours) as actualhours FROM `testing-bi-engine.starschema.actual`
WHERE date <= PARSE_DATE('%Y%m%d', @DS_END_DATE)
group by category, commodity) t2
on t0.category= t2.category and t0.commodity= t2.commodity
left outer join
(SELECT category, commodity , sum(budgethours) as budgethours FROM `testing-bi-engine.starschema.budget`
group by category, commodity) t3
on t0.category= t3.category and t0.commodity= t3.commodity
left outer join
(SELECT category, commodity , sum(forecast) as forecast FROM `testing-bi-engine.starschema.baseline`
  WHERE date <= PARSE_DATE('%Y%m%d', @DS_END_DATE)
group by category, commodity) t4
on t0.category= t4.category and t0.commodity= t4.commodity
group by t0.category, t0.commodity

это типичная схема типа «звезда» с таблицей из нескольких фактов enter image description here

мой вопрос, есть ли лучший способ написать этот запрос?

1 Ответ

1 голос
/ 02 ноября 2019

есть ли лучший способ написать этот запрос?

Попробуйте ниже:

Рефакторинг - Раунд 1

Удалено ненужное (самое внешнее) GROUP BY с SUMs и заменил многословный ON на более компактный USING

#standardSQL
WITH t0 AS ( 
  SELECT category, commodity FROM `testing-bi-engine.starschema.budget` UNION DISTINCT
  SELECT category, commodity FROM `testing-bi-engine.starschema.actual` UNION DISTINCT
  SELECT category, commodity FROM `testing-bi-engine.starschema.baseline`
)
SELECT category, commodity, 
  actualhours , 
  budgethours , 
  forecast 
FROM t0 LEFT OUTER JOIN (
  SELECT category, commodity , SUM(actualhours) AS actualhours 
  FROM `testing-bi-engine.starschema.actual`
  WHERE date <= PARSE_DATE('%Y%m%d', @DS_END_DATE)
  GROUP BY category, commodity
) t2 USING(category, commodity)
LEFT OUTER JOIN (
  SELECT category, commodity , SUM(budgethours) AS budgethours 
  FROM `testing-bi-engine.starschema.budget`
  GROUP BY category, commodity
) t3 USING(category, commodity)
LEFT OUTER JOIN (
  SELECT category, commodity , SUM(forecast) AS forecast 
  FROM `testing-bi-engine.starschema.baseline`
  WHERE date <= PARSE_DATE('%Y%m%d', @DS_END_DATE)
  GROUP BY category, commodity
) t4 USING(category, commodity)

Рефакторинг - Раунд 2

Исключено t0, поскольку это не такдействительно необходимо, заменяя таким образом LEFT OUTER на FULL OUTER

#standardSQL
SELECT category, commodity, 
  actualhours , 
  budgethours , 
  forecast 
FROM (
  SELECT category, commodity , SUM(actualhours) AS actualhours 
  FROM `testing-bi-engine.starschema.actual`
  WHERE date <= PARSE_DATE('%Y%m%d', @DS_END_DATE)
  GROUP BY category, commodity
) t2 
FULL OUTER JOIN (
  SELECT category, commodity , SUM(budgethours) AS budgethours 
  FROM `testing-bi-engine.starschema.budget`
  GROUP BY category, commodity
) t3 USING(category, commodity)
FULL OUTER JOIN (
  SELECT category, commodity , SUM(forecast) AS forecast 
  FROM `testing-bi-engine.starschema.baseline`
  WHERE date <= PARSE_DATE('%Y%m%d', @DS_END_DATE)
  GROUP BY category, commodity
) t4 USING(category, commodity)
...