Обобщение параметризованного запроса - PullRequest
0 голосов
/ 05 февраля 2020

Я создал (с помощью StackOverflow!) Довольно сложный запрос SQL для проведения когортного анализа того, как покупка определенного продукта влияет на доход.

Я создал его для параметризации, чтобы запрос может быть передан ${PRODUCT} как продукт для оценки, и он сгенерирует отчет.

SELECT 
  DATE_DIFF(PARSE_DATE("%Y-%m", month), PARSE_DATE("%Y-%m", earliest_use), MONTH) as nplus,
  CASE WHEN ProductName = '${PRODUCT}' THEN '${PRODUCT}' ELSE 'Other' END as product,
  CustomerInfo,
  AVG(net_revenue) as avg_net_revenue,
  COUNT(DISTINCT CustomerID) as customers
FROM (
SELECT 
  month,
  rev.CustomerID,
  ProductName,
  customers.CustomerInfo,
  SUM(Revenue) AS net_revenue,
  MIN(MIN(CASE WHEN ProductName = '${PRODUCT}' THEN month END)) OVER (PARTITION BY rev.CustomerID) AS earliest_use 
FROM
  RevenueTable as rev,
  CustomerTable AS customers 
WHERE
  customers.CustomerID = rev.CustomerID
  AND rev.CustomerID IN (
      SELECT DISTINCT CustomerID
      FROM RevenueTable
      WHERE ProductName = '${PRODUCT}'
    )
GROUP BY 1,2,3,4
)
GROUP BY nplus, product, CustomerInfo
HAVING nplus >= -7
ORDER BY nplus

Однако теперь я хочу создать универсальную c версию, которая просто повторяет этот запрос по ВСЕМ продуктам .

Любая помощь будет высоко ценится.

1 Ответ

1 голос
/ 21 февраля 2020

Если вы используете CLI для запуска вашего параметризованного запроса , вы можете использовать такой скрипт:

bq query --format=csv --use_legacy_sql=false  'SELECT product_desc FROM `PROJECT.DATASET.products_list`' | xargs -I {} bq query --use_legacy_sql=false --parameter=product::{} 'SELECT fact_id, product_desc FROM  `PROJECT.DATASET.product_fact_table` WHERE product_desc = @product'

В этом скрипте я запрашиваю название продуктов из таблица с именем «products_list» и последующая передача каждого запроса, который получает все операции, связанные с указанным c продуктом в таблице с именем «product_fact_table». Результат выглядит так:

script result

С другой стороны, если вы используете API или некоторые клиентские библиотеки (Go, Java, Node.js или Python), я думаю, вам нужно только собрать все oop в соответствии с языком программирования, который вы используете.

В настоящее время интерфейс BigQuery не поддерживает параметризованные запросы.

Кроме того, я хотел бы поделиться с вами дополнительной альтернативой, используя Сценарии :

DECLARE count INT64 default 0;
DECLARE target_product STRING;
DECLARE products_array ARRAY<STRING>;
DECLARE number_of_products INT64;

SET number_of_products = (
WITH products AS
  (SELECT ARRAY (select product_desc from `PROJECT_ID.DATASET.products_list`) as products_result)
SELECT ARRAY_LENGTH(products_result) AS len
FROM products);

SET products_array = (
      SELECT ARRAY_AGG(product_desc)
      FROM `PROJECT_ID.DATASET.products_list`
    ); 

LOOP  
  SET target_product = products_array[OFFSET(count)];
  SELECT * FROM `PROJECT_ID.DATASET.product_fact_table` WHERE product_desc=target_product;
  SET count = count + 1;
  IF count >= number_of_products THEN
    LEAVE;
  END IF;
END LOOP;

Здесь я объявляю переменную "count" и использую ее для посчитать количество обработанных итераций, переменная «target_product» содержит название продукта на каждой итерации, «products_array» устанавливается со всеми продуктами из запроса и, наконец, «number_of_products» содержит общее количество продуктов и используется для ограничения количества итераций l oop.

...