Как я могу связать эти строки вместе в запросе SQL в BigQuery? (Я думаю, что это требует рекурсии CTE, что BigQuery, похоже, не нравится ...) - PullRequest
0 голосов
/ 09 июля 2019

любая помощь с благодарностью. Довольно озадачен этим! Любитель SQL, но думаю, что BigQuery мне здесь не поможет.

У меня есть таблица, которая выглядит примерно так:

Object  ID1 ID2
A   1   null
B   2   1
C   3   2
D   4   3

A, B, C и D на самом деле являются одним и тем же объектом. Вы можете видеть, что они связаны «цепочкой» дочерних идентификаторов. А является «главным» объектом.

Я хотел бы новый столбец в этой таблице, который возвращает «A» (или эквивалентный) для связанных объектов (вызывая это P1-Obj). Вот как бы я хотел, чтобы результат выглядел так:

P1-Obj  Object  ID1 ID2
A   A   1   null
A   B   2   1
A   C   3   2
A   D   4   3
E   E   5   null
E   F   6   5
E   G   7   6
E   H   8   7

Это должно работать с «цепочками» произвольной длины (то есть может иметь 0-100 объектов, подключенных к P1-Obj).

Я решил эту проблему в электронной таблице, используя эту формулу - представив, что в приведенной выше таблице есть столбцы AD, эта формула работает, если поместить ее в столбец A: = IF (ISBLANK ($ D2), $ B2, INDIRECT ("A" & MATCH ( $ D2, $ C: $ С, 0))). Мне нужен SQL-эквивалент этого!

До сих пор я пытался использовать CTE с рекурсией, чтобы начать работу со структурой данных, с которой я мог бы работать, чтобы перейти к описанному выше.

Что-то вроде:

WITH cte as (
    SELECT *
    FROM table
    where ID2 is null
    UNION ALL
    SELECT m.*
    FROM table m 
    JOIN cte o
    on m.ID1 = o.ID2) 
select * 
from cte

Но BigQuery выплевывает: «Таблица имен» таблицы «отсутствует набор данных, хотя в запросе не задан набор данных по умолчанию» - и в быстром Google это выглядит как рекурсивные CTE не поддерживаются в BigQuery.

Я даже не уверен, что рекурсивный CTE - это то, что мне нужно, чтобы начать решать мою проблему, но я не смог даже увидеть вывод - и на каждом другом проспекте Google есть завел меня в тупик.

Я довольно озадачен тем, что есть ли другой способ сделать это в BigQuery (или вообще с SQL)!

Заранее большое спасибо за любые советы.

РЕДАКТИРОВАТЬ: Добавлено Fiddle: https://www.db -fiddle.com / f / m6EN38upDhFLt7eUwtKrLa / 3

Не уверен, что он делает то, что мне нужно ...

Ответы [ 2 ]

3 голосов
/ 10 июля 2019

Как это?

WITH RECURSIVE table2 (root_pn, pn, id1, id2) AS
(
  SELECT pn as root_pn, pn, id1, id2
    FROM table1
    WHERE id2 IS NULL
  UNION ALL
  SELECT root_pn, c.pn, c.id1, c.id2
    FROM table2 AS cp JOIN table1 AS c
      ON cp.id1 = c.id2
)
SELECT * FROM table2
ORDER BY root_pn;
0 голосов
/ 10 июля 2019

Закрытия уровней могут выполнять свою работу при работе с иерархиями.Можно быстро прочитать их здесь

Пример скрипта здесь: https://www.db -fiddle.com / f / igzuLfJzsh7nmr2r3w5L5W / 5

jist заключается в том, что вы создаете таблицу замыкания, которая содержит всех предков и потомков, а затем используете ее для запроса, например, так:

SELECT t2.pn as `p1-obj`, t1.pn, t1.id, t1.ancestor
FROM t1
JOIN t1_closure t1c ON t1.id = t1c.descendant
JOIN t1 t2 ON t1c.ancestor = t2.id
WHERE t1c.ancestor IN (1, 5);

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

WHERE t1c.ancestor IN (
    # Sub Query here
);
...