2015-10-23 2 views
1

Мои данные выглядит следующим образом:Глубина в древовидной структуре в BigQuery

| child_id | parent_id | 
| 10 | Null | 
| 13 |  10 | 
| 15 |  13 | 
| 11 |  10 | 
| 16 |  11 | 
| 19 |  15 | 

Это можно рассматривать как дерево. Теперь я хочу определить глубину каждого child_id. Так что пример должен быть:

| child_id | parent_id | depth | 
| 10 | Null | 0 | 
| 13 |  10 | 1 | 
| 15 |  13 | 2 | 
| 11 |  10 | 1 | 
| 16 |  11 | 2 | 
| 19 |  15 | 3 | 

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

ответ

1

Я просто написал запрос для этого, используя только что опубликованный «полный набор данных хакерских новостей на BigQuery».

Проблема заключается в том, что некоторые комментарии указывают на родительскую историю, в то время как комментарии других комментариев к родительским комментариям и поиск исходной истории через них затруднены (так как это рекурсивная операция). Решаемый с помощью:

SELECT p0.id, s.id, s.title, level 
    FROM (
    SELECT p0.id, p0.parent, p2.id, p3.id, p4.id, COALESCE(p7.parent, p6.parent, p5.parent, p4.parent, p3.parent, p2.parent, p1.parent, p0.parent) story_id, 
      GREATEST(IF(p7.parent IS null, -1, 7), IF(p6.parent IS null, -1, 6), IF(p5.parent IS null, -1, 5), IF(p4.parent IS null, -1, 4), IF(p3.parent IS null, -1, 3), 
        IF(p2.parent IS null, -1, 2), IF(p1.parent IS null, -1, 1), 0) level 
    FROM [fh-bigquery:hackernews.comments] p0 
    LEFT JOIN EACH [fh-bigquery:hackernews.comments] p1 ON p1.id=p0.parent 
    LEFT JOIN EACH [fh-bigquery:hackernews.comments] p2 ON p2.id=p1.parent 
    LEFT JOIN EACH [fh-bigquery:hackernews.comments] p3 ON p3.id=p2.parent 
    LEFT JOIN EACH [fh-bigquery:hackernews.comments] p4 ON p4.id=p3.parent 
    LEFT JOIN EACH [fh-bigquery:hackernews.comments] p5 ON p5.id=p4.parent 
    LEFT JOIN EACH [fh-bigquery:hackernews.comments] p6 ON p6.id=p5.parent 
    LEFT JOIN EACH [fh-bigquery:hackernews.comments] p7 ON p7.id=p6.parent 
    HAVING level=0 
    LIMIT 100 
) a 
    LEFT JOIN EACH [fh-bigquery:hackernews.stories] s 
    ON s.id=a.story_id 

(имея так много слева присоединяется потребляет много ресурсов, поэтому, чтобы запустить его в широком масштабе, я бы искать другую стратегию)

https://news.ycombinator.com/item?id=10440502

+0

Это необходимо заранее определенную сумму глубины ... может ли это как-то быть более общим для учета каждой отдельной глубины? – fsociety

+0

Поскольку алгоритмы обхода дерева являются рекурсивными, вам нужно либо выполнить один и тот же запрос рекурсивно семь раз, либо написать запрос, который выходит за семь уровней за один проход. Но если вам нужно больше, чем x уровней, то рекурсия. Или это то, что я догадался до сих пор. –

Смежные вопросы