2012-02-17 3 views
0

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

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

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

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

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 с решением, то мне было бы интересно чтобы увидеть это.

Благодаря

ответ

3
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 
+0

Я предполагаю, что '* 1.0' означает, что' AVG' производит float, а не целое число? –

+0

@ Remnant - Да. В противном случае вы получили бы '25', считая, что' Age' is и 'int'. –

+0

@Remnant - На самом деле это не 'float', а' numeric (38,6) 'в этом случае. –

1

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

Select 
UserID, 
Age, 
(select Max(Age) from Users) as 'AvgAge' 
    From Users 
    Where UserID = 1 
1
SELECT 
    u.UserId, 
    u.Age, 
    b.AvgAge 
FROM 
    dbo.Users a, 
    (SELECT AVG(Age*1e0) as AvgAge FROM dbo.Users) as b 
+0

Там это не 'WHERE' пункт, чтобы указать пользователя? –

+0

Результатом будет таблица пользователей со средним возрастом (на самом деле всегда одинаковое число для каждого запроса), поэтому, если вы хотите добавить предложение WHERE, это базовые знания SQL. WHERE u.UserId = alexsuslin

+0

Большое спасибо. +1. Мой комментарий о 'WHERE' был написан беззаботно! –

1
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 
+0

Что делает '1 = 1'? –

+0

Просто условие, чтобы заставить соединение соответствовать каждой записи (в этом случае только одна запись) – Sparky

2

Этот запрос исключает пользователя с указанным идентификатором от среднего значения, в соответствии с просьбой , Вы использовали 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 
+0

Спасибо. '+ 1'. Я отвечу с ответом Mikael, поскольку его запрос возвращает float, тогда как ваш запрос возвращает целое число «26», но так же хорошо. Благодарю. –

+0

Прохладный. MySQL возвращает float, так что это хорошая небольшая обломанность SQL-Server, которую я узнал сегодня :) –

1
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 
Смежные вопросы