SOTorrent:仅选择那些带有“ android”标签的线程的答案吗?

时间:2018-10-07 08:51:01

标签: sql google-bigquery

数据集: SOTorrent-这是数据集(托管在Google的BigQuery上):您可以在此处运行查询。它有一个Posts表。尽管我试图解释以下相关字段,但仍可以在此处找到帖子表的详细架构,以供您参考:SO Schema

SO:StackOverflow

背景:数据集有一个名为帖子的表格。在该表中,存在一个字段 PostTypeId

  • 如果该字段为1,则表示我们正在查看的帖子是在SO上发布的问题。在这种情况下,另一个名为 Tags 的字段将包含问题的OP在SO上分配的标签。

  • 如果该字段为2,则为在SO上发布的答案。在这种情况下,标签字段将为空。

问题:仅选择那些已附加Android标签的线程的所有答案。

我的解决方案:

SELECT
 p.Id,
 p.Score,
 p.body
FROM
  [sotorrent-org:2018_09_23.Posts] p
WHERE
  p.Tags LIKE "%android%"
  AND p.PostTypeId = 2 
LIMIT
  10

但是,很明显,上面的查询将返回null,因为WHERE子句检查不能共存的条件。如果帖子带有标签,则不能作为答案。如果是答案,则不能包含标签。

如何解决此问题并在同一张表上检查两个互斥条件?

2 个答案:

答案 0 :(得分:3)

您需要使用ParentId字段将posts表与其自身相连:

#standardSQL
SELECT
  answer.Id
, answer.Score
, answer.body
FROM
  `sotorrent-org.2018_09_23.Posts` question
JOIN
  `sotorrent-org.2018_09_23.Posts` answer
ON
      answer.ParentId=question.Id
  AND answer.PostTypeId=2
  AND question.PostTypeId=1
WHERE
      question.Tags LIKE "%android%"
  AND question.PostTypeId = 1
  AND answer.PostTypeId = 2
LIMIT
  10

答案 1 :(得分:0)

如果我理解正确,我认为最好的方法是窗口函数:

SELECT p.Id,  p.Score p.body
FROM (SELECT p.*,
             MAX(p.tags) OVER (PARTITION BY COALESCE(p.parentid, p.id)) as tags
      FROM `sotorrent-org.2018_09_23.Posts` p
     )
WHERE p.Tags LIKE '%android%' AND
      p.PostTypeId = 2 
LIMIT 10;

这应该更快。