Reputation: 12487
I am struggling with a SQL query that I initially thought should be quite simple.
Imagine a table Users
that uses a UserID
as the PK and a column Age
for the users age:
UserID Age
1 22
2 34
3 23
4 19
etc.
I'd like to be able to specify a UserID and return that user's age as well as the average age of all other users. For example, if I specify UserID 1 then I'd like to see return set as:
UserID Age AvgAge
1 22 24.5
The following does not work: (as the WHERE
is performed before GROUP BY
)
Select UserID, Age, Avg(Age) as 'AvgAge'
From Users
Where UserID = 1
Group By UserId, Age
UserID Age AvgAge //Result set
1 22 22
Can anybody nudge me in the right direction?
By the way, in an ideal world the average age should not include the user that has been specified as the idea is to show their age relative to the average age of everybody else.
Given that there are 1000+ users then taking an average over all users will make no practical difference to the AvgAge
number, though if anybody would like to show off their SQL prowess with a solution to that then I'd be interested to see it.
Thanks
Upvotes: 0
Views: 416
Reputation: 44326
declare @T table (UserID int, Age int)
insert into @T values(1,22),(2,34),(3,23),(4,19)
declare @UserID int = 1
;with a as
(
select userid, Age,
avg(age * case when userid <> @userid then 1.0 end) over() 'AvgAge'
from @T
)
select Age, AvgAge from a
where userid = @UserID
Upvotes: 1
Reputation: 4225
SELECT
u.UserId,
u.Age,
b.AvgAge
FROM
dbo.Users a,
(SELECT AVG(Age*1e0) as AvgAge FROM dbo.Users) as b
Upvotes: 1
Reputation: 138970
declare @T table
(
UserID int,
Age int
)
insert into @T values
(1, 22),
(2, 34),
(3, 23),
(4, 19)
declare @UserID int = 1
select Age, (select avg(Age*1.0)
from @T
where UserID <> @UserID) as AvgAge
from @T
where UserID = @UserID
Result:
Age AvgAge
----------- ---------------------------------------
22 25.333333
Upvotes: 3
Reputation: 14959
This query excludes the user with the specified id from the average, as requested. You used MAX in your example, which is not going to give you the average, but if MAX is actually what you want, you can just swap it with AVG in this query and it'll work.
SELECT u.UserID,
u.Age,
(SELECT AVG(uavg.Age)
FROM Users uavg
WHERE uavg.UserID != u.UserID) AS AvgAge
FROM Users u
WHERE u.UserID = 1
Upvotes: 2
Reputation: 15095
Select U.UserID, u.Age, sq.Age as 'AvgAge'
From Users u
join (select average(age) as Age from users) sq on 1=1
Where UserID = 1
Group By UserId, Age
Upvotes: 1
Reputation: 8333
use what you need avg
for average and max
for maximum age:
Select
UserID,
Age,
(select Max(Age) from Users) as 'AvgAge'
From Users
Where UserID = 1
Upvotes: 1