BigQuery: коррелированные подзапросы, которые ссылаются на другие таблицы, не поддерживаются, если их нельзя декоррелировать - PullRequest
0 голосов
/ 08 апреля 2020

Когда я запускаю свой запрос на реальных таблицах, я получаю сообщение об ошибке:

Correlated subqueries that reference other tables are not supported unless they can be de-correlated, such as by transforming them into an efficient JOIN

Вот точный запрос, который я выполняю:

SELECT
CASE WHEN addresses LIKE '%,%'
THEN
(
SELECT STRING_AGG(DISTINCT address) addresses
FROM VW_CLEAN.TABLE_1
WHERE member_id = el.member_id
AND eligible_month < el.eligible_month
GROUP BY member_id, eligible_month
ORDER BY eligible_month DESC 
LIMIT 1
) 
END AS address,
eligible_month, 
member_id
FROM
(
    SELECT STRING_AGG(DISTINCT address) addresses, eligible_month, member_id FROM
    (
        SELECT DISTINCT address, eligible_month, member_id
        FROM VW_CLEAN.TABLE_1
        UNION ALL
        SELECT DISTINCT address, eligible_month, member_id
        FROM VW_CLEAN.TABLE_2
    )
    GROUP BY eligible_month, member_id
) el
WHERE member_id IS NOT NULL
AND eligible_month IS NOT NULL

Но когда я подготовил тот же запрос, но для тестовых данных, используя «WITH AS», он выполняется без ошибки.

#standardSQL
WITH table_1 AS (
  SELECT "201905" AS month, "11111" AS member, "123" AS address
  UNION ALL
  SELECT "201903" AS month, "11111" AS member, "234" AS address
  UNION ALL
  SELECT "201902" AS month, "11111" AS member, "345" AS address
  UNION ALL
  SELECT "201902" AS month, "22222" AS member, "456" AS address
  UNION ALL
  SELECT "201901" AS month, "22222" AS member, "567" AS address
),
table_2 AS (
  SELECT "201904" AS month, "11111" AS member, "678" AS address
)

SELECT 
a.member,
a.month,
(
  SELECT STRING_AGG(address) address
  FROM table_1
  WHERE member = a.member
  AND month < a.month
  GROUP BY member, month
  ORDER BY month DESC 
  LIMIT 1
) AS previous_address
FROM
(
    SELECT STRING_AGG(address) address, month, member
    FROM
    (
        SELECT month, member, address
        FROM table_1
        UNION ALL
        SELECT month, member, address
        FROM table_2
    )
    GROUP BY month, member
    HAVING member = '11111' AND month = '201905'
) a

Так в чем же разница между реальными таблицами и таблицами, созданными с использованием «WITH AS»?

Редактору требуется больше текста для сохранения описания, поэтому я добавляю ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ

Ответы [ 2 ]

1 голос
/ 09 апреля 2020

Я не знаю точного ответа на ваш вопрос, однако могу сказать, что ваш запрос не является одним из лучших методов.

Я бы хотел узнать больше о ваших таблицах table1 и table2. лучший запрос, но сейчас я буду обрабатывать его как одну таблицу, чтобы получить предыдущий адрес для члена.

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

WITH table_1 AS (
  SELECT "201905" AS month, "11111" AS member, "123" AS address
  UNION ALL
  SELECT "201903" AS month, "11111" AS member, "234" AS address
  UNION ALL
  SELECT "201902" AS month, "11111" AS member, "345" AS address
  UNION ALL
  SELECT "201902" AS month, "22222" AS member, "456" AS address
  UNION ALL
  SELECT "201901" AS month, "22222" AS member, "567" AS address
),
table_2 AS (
  SELECT "201904" AS month, "11111" AS member, "678" AS address
)
SELECT 
  *,
  lag(address) over (partition by member order by month) previous_address,
  last_value(t1_address ignore nulls) over (partition by member order by month rows between unbounded preceding and 1 preceding) as previous_t1_address
FROM 
(
    SELECT month, member, address, address as t1_address
    FROM table_1
    UNION ALL
    SELECT month, member, address, null
    FROM table_2
);
0 голосов
/ 10 апреля 2020

Согласно документации.

Псевдонимы предложения FROM не видны подзапросам в том же предложении FROM. Подзапросы в предложении FROM не могут содержать коррелированные ссылки на другие таблицы в этом же предложении FROM.

В вашем случае вы используете поля el.member_id и el .elitable_month и на основании упомянутого выше сообщения таблица el невидима для подзапросов.

В здесь вы можете найти больше примеров о недопустимом корреляте подзапросы.

Однако рекомендуется использовать оператор WITH.

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