Как использовать подзапрос IN в динамическом списке c в SQL? - PullRequest
1 голос
/ 01 мая 2020

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

Cannot execute IN subquery with uncomparable types INT64 and STRUCT<INT64, INT64>

С запросом:

WITH vars AS (
  SELECT (3,6) as ids
)
SELECT id FROM users
WHERE id IN (SELECT ids FROM vars);

Это сбивает с толку, потому что я подумал, что это именно то, для чего был подзапрос IN. Я не понимаю, почему этот запрос не выполняется, в то время как следующий запрос работает нормально:

SELECT id FROM users
WHERE id IN (3,6);

В чем здесь проблема и есть ли обход?

Ответы [ 3 ]

3 голосов
/ 01 мая 2020

Мой любимый / самый простой способ решения начального запроса:

WITH vars AS (
  SELECT [3,6] as ids
)
SELECT i FROM `fh-bigquery.public_dump.numbers_255` 
WHERE i IN UNNEST((SELECT ids FROM vars));

Секрет:

  • В переменных используйте [] вместо (), чтобы вернуть массив.
  • В основном запросе обязательно UNNEST().
1 голос
/ 01 мая 2020

Это не делает то, что вы думаете:

SELECT (3,6) as ids

Это создает запись с двумя безымянными столбцами. Итак, если вы запустите:

WITH vars AS (
  SELECT [3,6] as ids
)
SELECT * 
FROM vars;

Результат:

ids._field_1    ids._field_2        
   3                  6

Вы можете приблизиться к тому, что вы хотите, используя массивы:

WITH vars AS (
  SELECT [3,6] as ids
)
SELECT u.id
FROM users u
WHERE u.id IN (SELECT v.id FROM vars v CROSS JOIN UNNEST(v.ids) id);

Хотя в На практике это часто записывается как:

WITH vars AS (
  SELECT [3,6] as ids
)
SELECT u.id
FROM users u JOIN
     (vars CROSS JOIN
      UNNEST(v.ids) id
     )
     ON u.id = id;

Или, более подробная форма без массивов:

WITH vars AS (
  SELECT 3 as id UNION ALL
  SELECT 6
)
SELECT u.id
FROM users u
WHERE u.id IN (SELECT v.id FROM vars v);
0 голосов
/ 01 мая 2020

Ниже для BigQuery Standard SQL

WITH vars AS (
  SELECT 3 AS ids UNION ALL
  SELECT 6
)
SELECT id FROM users
WHERE id IN (SELECT ids FROM vars);  

ИЛИ

WITH vars AS (
  SELECT '3,6' ids
)
SELECT id FROM users
WHERE id IN (SELECT CAST(ids AS INT64) FROM vars, unnest(SPLIT(ids)) ids);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...