the following :
(在 Stack Exchange Data Explorer 上运行查询,该查询使用OData的SQL Azure实现。 FAQ 表示它支持大多数 TSQL 命令):
DECLARE @MinPosts int = ##MinNumberOfPosts##
SELECT
Id AS [User Link],
Reputation,
(SELECT COUNT(*)
FROM posts
WHERE posts.OwnerUserId = Users.Id
) AS [# Posts],
Reputation /
(SELECT COUNT(*)
FROM posts
WHERE posts.OwnerUserId = Users.Id
) AS [Rep Per Post]
FROM Users
WHERE (SELECT COUNT(*)
FROM posts
WHERE posts.OwnerUserId = Users.Id
) > @MinPosts
ORDER BY [Rep Per Post] DESC
我写出来了:
(SELECT COUNT(*)
FROM posts
WHERE posts.OwnerUserId = Users.Id)
三次。 如何为上述代码片段创建变量或函数?
我尝试使用列别名[# Posts]
,但这不起作用。
我发现 these posts 重新使用计算的字段名称进行进一步计算,这似乎是我想要的,但我无法弄清楚如何应用它。
答案 0 :(得分:3)
由于您需要整个数据库中每个用户的计数以及每个帖子,只需按照简单的方式进行:
SELECT
Id AS [User Link],
Reputation,
Reputation * 1.0 / C.Cnt AS [Rep Per Post]
FROM
Users U
INNER JOIN (
SELECT OwnerUserId, Cnt = Count(*)
FROM posts
GROUP BY OwnerUserID
HAVING Count(*) >= ##MinNumberOfPosts##
) C ON U.Id = C.OwnerUserId
ORDER BY [Rep Per Post] DESC
您可能会发现这提供了与CROSS APPLY解决方案相同的执行计划,但这只是因为引擎足够聪明以避免相关子查询并将其切换为此查询明确表示的简单聚合。如果CROSS APPLY确实表现得更好,我很有兴趣知道原因。
P.S。我添加了* 1.0
,因为我猜测(这里不确定引擎)整数除法产生整数,看起来你可能想要分数。你必须进行实验。
答案 1 :(得分:1)
您可以使用CROSS APPLY
,
DECLARE @MinPosts int = ##MinNumberOfPosts##
SELECT
Id AS [User Link],
Reputation,
counts.[# Posts],
Reputation / counts.[# Posts] AS [Rep Per Post]
FROM Users
CROSS APPLY (
SELECT COUNT(*)
FROM posts
WHERE posts.OwnerUserId = Users.Id
) counts([# Posts])
WHERE counts.[# Posts] > @MinPosts
ORDER BY [Rep Per Post] DESC