Как обратиться к другому полю, вычисленному в предложении WHERE? - PullRequest
2 голосов
/ 31 января 2020

Рассмотрим упрощенный пример:

SELECT
  lengthy_expression AS a,
  g(a) AS b,
  h(a) AS c,
  ...
FROM
  my_table

Здесь lengthy_expression представляет сложное выражение, которое использует несколько полей из my_table и занимает несколько строк. Его результат используется для вычисления двух других полей b и c. Тем не менее, вышеупомянутое не допускается в стандартном SQL, потому что выражение в предложении WHERE не может ссылаться на результат другого выражения в предложении WHERE (почему бы не выйти за рамки меня).

Наивный вариант - повторить lengthy_expression, но этого я явно хочу избежать.

Один вариант - использовать подзапрос:

SELECT
  a,
  g(a) AS b,
  h(a) AS c,
  ...
FROM (
  SELECT
    lengthy_expression AS a,
    ...
  FROM
    my_table
)

Но, как вы можете видите, теперь мне нужно повторить другие поля ..., которые нужны внешнему запросу.

Может быть, тогда подзапрос с объединением?

SELECT
  a,
  g(a) AS b,
  h(a) AS c,
  ...
FROM
  my_table
INNER JOIN (
  SELECT
    lengthy_expression AS a
  FROM
    my_table
) USING id

Это работает, но теперь есть ( возможно, дорогое) объединение, которое не преследует никакой цели, кроме как для обеспечения удобства чтения запроса. И это даже не очень хорошо подходит для этой цели, потому что lengthy_expression спрятан ниже точки, где он используется, и читатель должен прыгнуть повсюду, чтобы узнать, что происходит.

Альтернативой является использование CTE:

WITH
my_table_with_a AS (
  SELECT
    *,
    lengthy_expression AS a
  FROM
    my_table
)
SELECT
  *,
  g(a) AS b,
  h(a) AS c,
  ...
FROM
  my_table_with_a

По крайней мере, теперь порядок чтения более или менее соответствует логическому порядку, в котором происходят операции, но он довольно многословен, и найти хорошее имя для my_table_with_a сложно. Тем более, что на практике я повторяю этот шаблон два или три раза.

Есть ли лучший способ сделать это?

Ответы [ 2 ]

2 голосов
/ 31 января 2020

Ниже для BigQuery Standard SQL

#standardSQL
SELECT 
  a,
  g(a) AS b,
  h(a) AS c,
FROM `project.dataset.my_table`,
UNNEST([lengthy_expression]) a   

Ниже приведен чрезвычайно упрощенный пример вышеприведенного подхода

#standardSQL
WITH `project.dataset.my_table` AS (
  SELECT 1 x, 2 y, 3 z UNION ALL
  SELECT 4, 5, 6
)
SELECT 
  a,
  a / 2 AS b,
  2 * a AS c
FROM `project.dataset.my_table`,
UNNEST([x + y + z]) a   
WHERE a > 10    

с результатом

Row a   b   c    
1   15  7.5 30   

Примечание: в случае, если результат lengthy_expression является ARRAY сам по себе - вам нужно заключить его в структуру, так как массив Big не поддерживается в BigQuery

0 голосов
/ 31 января 2020

Просто используйте *:

SELECT a, g(a) AS b, h(a) AS c, ...
FROM (SELECT lengthy_expression AS a, t.*
      ...
      FROM my_table t
     ) t

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...