计算用户平均体重
我有两个表,Users和DoctorVisit
用户
用户身份
姓名
医生来访
用户身份
重量
日期
doctorVisit表包含特定用户对医生的所有访问。
记录每次访问的用户体重。
查询:使用上次医生就诊的电话号码汇总所有用户的体重。 (然后除以用户数即可得出平均体重)
注意:某些用户可能根本没有去看医生,而其他用户可能已经去过很多次。
我需要所有用户的平均体重,但要使用最新的体重。
更新
我想要所有用户的平均体重。
解决方案
如果他们访问过,这应该为我们提供每位用户的平均体重:
select user.name, temp.AvgWeight from user left outer join (select userid, avg(weight) from doctorsvisit group by userid) temp on user.userid = temp.userid
编写查询以选择每个用户的最新权重(QueryA),并将该查询用作查询的内部选择以选择平均值(QueryB),例如,
SELECT AVG(weight) FROM (QueryA)
如果我正确理解了问题,那么我们应该能够根据以下SQL语句基于所有用户的上次访问来获得所有用户的平均权重。我们使用子查询来获取最后一次访问作为过滤器。
SELECT avg(uv.weight) FROM (SELECT weight FROM uservisit uv INNER JOIN (SELECT userid, MAX(dateVisited) DateVisited FROM uservisit GROUP BY userid) us ON us.UserID = uv.UserId and us.DateVisited = uv.DateVisited
我应该指出,这的确假设存在一个唯一的UserID,可以用来确定唯一性。另外,如果DateVisited不包括时间而是仅包含日期,则同一天访问两次的一位患者可能会使数据偏斜。
我认为规格有误。
如果按所有用户划分,则平均值将太低。没有看医生的每个用户将趋向于将平均值拖向零。我不相信那是我们想要的。
我懒得提出一个实际的查询,但是这将是其中之一,我们可以在基表和带有组的查询之间使用自联接,并通过该联接提取所有相关的Id,访问日期对从基本表。用户表唯一需要的是名称。
我认为,几个星期前,我们在这里有一个相同问题的样本。所谓"相同的问题",是指问题:我们想要一个组代表的属性,但是我们想要的属性没有包含在group by子句中。
我认为这会奏效,尽管我可能会错:
使用内部选择来确保我们最近访问过,然后使用AVG。在此示例中,User表是多余的:由于那里没有重量数据,而且我们也不在乎用户名,因此对其进行检查没有任何好处。
SELECT AVG(dv.Weight) FROM DoctorsVisit dv WHERE dv.Date = ( SELECT MAX(Date) FROM DoctorsVisit innerdv WHERE innerdv.UserID = dv.UserID )
如果使用的是SQL Server 2005,则不需要GROUP BY上的子查询。
我们可以使用新的ROW_NUMBER和PARTION BY功能。
SELECT AVG(a.weight) FROM (select ROW_NUMBER() OVER(PARTITION BY dv.UserId ORDER BY Date desc) as ID, dv.weight from DoctorsVisit dv) a WHERE a.Id = 1
正如其他人提到的那样,这是访问过医生的所有用户的平均体重。如果我们想要所有用户的平均体重,那么任何不去看医生的人都会给出一个令人误解的平均值。
这是我对解决方案的追求:
select avg(a.Weight) as AverageWeight from DoctorsVisit as a innner join (select UserID, max (Date) as LatestDate from DoctorsVisit group by UserID) as b on a.UserID = b.UserID and a.Date = b.LatestDate;
请注意,根本没有使用User表。
该平均值完全忽略了完全没有看医生或者在最近的医生就诊时其体重被记录为NULL的用户。如果任何用户在同一日期进行了多次访问,并且如果最新日期是该用户多次提出要求的那些日期之一,则该平均值将产生偏差。