2012-02-17 7 views
0

私は当初考えていたはずのSQLクエリに苦労しています。SQL - 他のすべての行の平均を持つ一意の行を選択してください

PKとしてUserIDとユーザーの年齢のための列Ageを使用するテーブルをUsers想像:私はユーザーIDを指定し、そのユーザの年齢を返すだけでなく、できるようにしたいと思い

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

他のすべてのユーザーの平均年齢。

UserID  Age  AvgAge 
    1   22  24.5 

が動作しない、次:(WHEREGROUP 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 

誰でもすることができます私は、ユーザーID 1を指定した場合たとえば、私はリターンのように設定してもらいたいです私を正しい方向に向ける?

ところで、理想的な世界では、平均年齢はではなく、には、他の人の平均年齢を基準にした年齢を表示するというアイデアが記載されています。

もし1000人以上のユーザーがいるとすれば、すべてのユーザーに平均をとってもAvgAgeという数字には実質的な違いはありませんが、その解決策を使ってSQLの腕前を見せたいと思ったら、それを見るために。要求されたよう

Select 
UserID, 
Age, 
(select Max(Age) from Users) as 'AvgAge' 
    From Users 
    Where UserID = 1 

答えて

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'が整数ではなく浮動小数点を生成することを保証すると仮定していますか? –

+0

@Remnant - はい。さもなければ、 'Age'が' int'であると仮定して '25'を得るでしょう。 –

+0

@Remnant - 実際には 'float'ではなく数値(38,6)です。 –

1

使用

感謝。あなたの例では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
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

単純に、すべてのレコードと一致するように結合を強制する条件(この場合は1レコードのみ) – Sparky

2

このクエリは、平均値から指定されたIDを持つユーザーを除外:あなたは平均および最大年齢maxためavgを必要とするもの

+0

ありがとうございます。 '+ 1'。あなたのクエリは整数26を返しますが、本当に良いものとして返されるのに対し、クエリは浮動小数点を返すので、私はMikaelの答えにつきます。ありがとう。 –

+0

クール。 MySQLは浮動小数点数を返すので、これは私が今日学んだ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 
関連する問題