SQL - выберите уникальную строку со средним значением всех других строк - PullRequest
0 голосов
/ 17 февраля 2012

Я борюсь с SQL-запросом, который изначально мне показался достаточно простым.

Представьте себе таблицу Users, которая использует UserID в качестве PK и столбец Age для возраста пользователей:

    UserID     Age
    1          22
    2          34
    3          23
    4          19
    etc.

Я бы хотел иметь возможность указать идентификатор пользователя и вернуть возраст этого пользователя, а также средний возраст всех остальных пользователей. Например, если я укажу UserID 1, я бы хотел, чтобы return был установлен как:

   UserID      Age      AvgAge
   1           22       24.5

Следующее не работает: (поскольку WHERE выполняется до 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

Кто-нибудь может подтолкнуть меня в правильном направлении?

Кстати, в идеальном мире средний возраст должен не включать пользователя, который был указан, поскольку идея состоит в том, чтобы показать свой возраст относительно среднего возраста всех остальных.

Учитывая, что существует более 1000 пользователей, тогда усреднение по всем пользователям не будет иметь практического значения для числа AvgAge, хотя, если кто-то захочет похвастаться своим мастерством SQL с помощью этого решения, то я буду интересно это увидеть.

Спасибо

Ответы [ 6 ]

3 голосов
/ 17 февраля 2012
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

Результат:

Age         AvgAge
----------- ---------------------------------------
22          25.333333
2 голосов
/ 17 февраля 2012

Этот запрос исключает пользователя с указанным идентификатором из среднего значения по запросу. Вы использовали MAX в своем примере, который не даст вам среднего значения, но если MAX действительно то, что вы хотите, вы можете просто поменять его с AVG в этом запросе, и он будет работать.

 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
1 голос
/ 17 февраля 2012
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
1 голос
/ 17 февраля 2012
  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
1 голос
/ 17 февраля 2012
SELECT 
    u.UserId, 
    u.Age, 
    b.AvgAge 
FROM 
    dbo.Users a, 
    (SELECT AVG(Age*1e0) as AvgAge FROM dbo.Users) as b
1 голос
/ 17 февраля 2012

используйте то, что вам нужно avg для среднего и max для максимального возраста:

Select 
 UserID, 
 Age, 
 (select Max(Age) from Users) as 'AvgAge'
  From Users
  Where UserID = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...