如何在SQL中使用变量或引用?

时间:2010-09-05 05:38:48

标签: sql sql-server tsql variables

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 重新使用计算的字段名称进行进一步计算,这似乎是我想要的,但我无法弄清楚如何应用它。

2 个答案:

答案 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​