In the following:
(running a query on the Stack Exchange Data Explorer, which uses an SQL Azure implementation of OData. The FAQ says it supports开发者_如何学运维 most of the TSQL commands):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
I write out:
(SELECT COUNT(*)
FROM posts
WHERE posts.OwnerUserId = Users.Id)
three times. How can I create a variable or a function for the above snippet of code?
I tried using the column alias [# Posts]
, but that didn't work.
I found these posts on reusing a calculated filed name for further calculation, which seems like what I want, but I can't figure out how to apply it.
Since you need the count for every user in the whole database and thus every post, just do it the straightforward way:
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
You may find this gives the same execution plan as the CROSS APPLY solution, but that would only be because the engine is clever enough to avoid the correlated subquery and switch it to a simple aggregate as this query explicitly denotes. If CROSS APPLY really performs better I'm quite interested to know why.
P.S. I added * 1.0
because I'm guessing (not sure of the engine here) that integer division yields integers and it seems like you'd probably want fractions. You'll have to experiment.
You can use 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
精彩评论