如何在 Stack Exchange Data Explorer 中获取所有用户的帖子标签(包括答案​​标签)?

How to get ALL users' posts' tags (include answer's tags) in the Stack Exchange Data Explorer?

我在 Stack Exchange Data Explorer (SEDE) 中使用查询。

这是my query:

SELECT A.Id
       , A.PostTypeId
       , A.Title
       , A.Body
       , A.ParentId
       , A.Tags
       , A.CreationDate
FROM   posts A
       LEFT JOIN users U
              ON A.OwnerUserId = U.id
WHERE  U.Id = ##UserId##
       AND A.PostTypeId = 1
UNION
SELECT A.Id
       , A.PostTypeId
       , A.Title
       , A.Body
       , A.ParentId
       , B.Tags
       , A.CreationDate
FROM   posts A
       LEFT JOIN users U
              ON A.OwnerUserId = U.id
       RIGHT JOIN posts B
               ON A.ParentId = B.Id
WHERE  U.Id = ##UserId##
       AND A.PostTypeId = 2

在上面的代码中,Stack Overflow 中的帖子有两种类型:问题和答案。问题(PostTypeId 在数据库模式中为 1)有标签,但答案(PostTypeId 在数据库模式中为 2)没有标签。 答案属于通过ParentId.

的问题

但是我上面的查询效率太低了,我只能得到一些(使用用户id)帖子的标签。

如何在 SEDE 超时时间内获取所有用户的帖子标签?

几件事:

  1. 您无法获取所有用户帖子的标签。 目前,there are over 41 million posts and SEDE limits results to 50,000 rows
  2. 因此,您需要:(A) 以某种方式限制结果 或 (B) 41 M posts, 50K at a time (NOT RECOMMENDED), or (C) use the Data Dump or Google's BigQuery($)
  3. 如果您不打算从 Users table 中提取任何内容,但不包括 ID,则不要包含 table。它会破坏循环,Posts.OwnerUserId 是一回事。
  4. 尽可能避免UNION语句(在这种情况下)。
  5. 如果使用 UNION 语句,请尽可能使用 UNION ALL(在这种情况下)。这使引擎不必进行重复检查。

所以,这里是 原始查询的执行计划:

这里是一个简化的计划:

the query that corresponds to it

SELECT      TOP 50000
            p.OwnerUserId                                       AS [User]
            , p.Id                                              AS [Post Id]
            , CASE WHEN p.PostTypeId = 1 THEN 'Q' ELSE 'A' END  AS [Type]
            , COALESCE (p.Title, ownr.Title)                    AS [Title]
            , p.Body
            , COALESCE (p.Tags, ownr.Tags)                      AS [Tags]
            , p.CreationDate
FROM        Posts p
LEFT JOIN   Posts ownr      ON ownr.ID = p.ParentId
WHERE       p.OwnerUserId   = ##UserId##
AND         p.PostTypeId    IN (1, 2)  -- Question, answer
ORDER BY    p.OwnerUserId DESC,  p.CreationDate

-- 这也提供了更具可读性的结果 -- 特别是当 WHERE 子句被删除时。

但是,如果你可以事先限制,比如说,用户;你得到一个偶数 more efficient query:

WITH usersOfInterest AS (
    SELECT      TOP 10
                u.Id                                                AS [UserId]
                , u.DisplayName
    FROM        Users u
    ORDER BY    u.Reputation DESC
)
SELECT      
            [User] = 'site://u/' + CAST(u.UserId AS NVARCHAR) + '|' + CAST(u.UserId AS NVARCHAR)
            , p.Id                                              AS [Post Id]
            , CASE WHEN p.PostTypeId = 1 THEN 'Q' ELSE 'A' END  AS [Type]
            , COALESCE (p.Title, ownr.Title)                    AS [Title]
            , p.Body
            , COALESCE (p.Tags, ownr.Tags)                      AS [Tags]
            , p.CreationDate
FROM        usersOfInterest u
INNER JOIN  Posts p         ON u.UserId = p.OwnerUserId
LEFT JOIN   Posts ownr      ON ownr.Id  = p.ParentId
WHERE       p.PostTypeId    IN (1, 2)   -- Question, answer
ORDER BY    u.UserId DESC,  p.CreationDate

(本次查询adds a convenient hyperlink到用户id。)

请注意,只有前 10 位用户的帖子超过 50K。