Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL嵌套查询,平均值_Sql_Postgresql_Nested_Average - Fatal编程技术网

SQL嵌套查询,平均值

SQL嵌套查询,平均值,sql,postgresql,nested,average,Sql,Postgresql,Nested,Average,我是SQL新手。 我有三个标签:医生、病人和就诊。 这样,每次“就诊”都会联系到前来就诊的患者。 这些字段是: 医生(did、dname、专科、诊所) 患者(pid、pname、bmi、性别) 访问(did、pid、vdate、费用) 我需要找到医生的id,他的病人的平均bmi是最大的。以及平均计算需要考虑的因素 每个患者的医生一次,即使患者多次就诊 我写了这个查询: SELECT V.did FROM Visit V NATURAL JOIN Patient P GROUP BY V.did

我是SQL新手。 我有三个标签:医生、病人和就诊。 这样,每次“就诊”都会联系到前来就诊的患者。 这些字段是:

医生(did、dname、专科、诊所)

患者(pid、pname、bmi、性别)

访问(did、pid、vdate、费用)

我需要找到医生的id,他的病人的平均bmi是最大的。以及平均计算需要考虑的因素 每个患者的医生一次,即使患者多次就诊

我写了这个查询:

SELECT V.did
FROM Visit V NATURAL JOIN Patient P
GROUP BY V.did 
HAVING AVG(P.bmi) >= ALL 
            (SELECT AVG(P.bmi)
            FROM Patient P NATURAL JOIN Visit V
            GROUP BY V.did)
ORDER BY did ASC
我的问题是,对于每个医生,我需要在平均计算中只考虑医生的每个患者一次,即使患者多次就诊,并且在我的查询中,我会根据患者在同一位医生中就诊的次数反复计算患者。
如何更改查询以满足需求?

请勿使用
自然加入
!列出
JOIN
键!这只是预防未来问题的好建议

如果您只需要一名医生,即使是在打领带的情况下,那么聚合、
orderby
,以及某种版本的
LIMIT
会满足您的需求

在标准SQL中,如下所示:

SELECT V.did
FROM Visit V JOIN
     Patient P
     USING (pid)
GROUP BY V.did 
ORDER BY AVG(P.bmi) DESC
FETCH FIRST 1 ROW ONLY;
NATURAL JOIN
最大的问题是它没有使用正确声明的
外键
关系。相反,它只依赖于具有相同名称的列。第二个大问题是键隐藏在查询中。因此,
JOIN
可能没有达到预期的效果,并且可能没有行或笛卡尔积,而且调试非常困难

查找患者平均bmi最大的医生id

您的基本查询将如下所示(Gordon Linoff已经评论说,
自然连接通常应该避免):

然后,你需要用领带筛选顶级医生。实际的解决方案取决于您的RDMBS

在Oracle中:

select d.did, d.dname, avg(p.bmi) avg_pmi
from doctor d
inner join visit on v.did = d.did
inner join patient p on p.pid = v.pid
group by d.did, d.dname
order by avg_pmi desc 
fetch first 1 row with ties
在SQL Server中:

select top (1) with ties d.did, d.dname, avg(p.bmi) avg_pmi
from doctor d
inner join visit on v.did = d.did
inner join patient p on p.pid = v.pid
group by d.did, d.dname
order by avg_pmi desc 
在其他系统中,如MySQL或Postgres,不支持带ties的
,通常可以使用窗口功能:

select did, dname, avg_pmi
from (
    select t.*, rank() over(order by avg_pmi desc) rn
    from (
        select d.did, d.dname, avg(p.bmi) avg_pmi
        from doctor d
        inner join visit on v.did = d.did
        inner join patient p on p.pid = v.pid
        group by d.did, d.dname
    ) t
) t
where rn = 1

用你正在使用的数据库标记你的问题。忘记自然连接结构。不要偷懒,指定连接条件。此外,如果稍后将一列添加到其中一个表中,并且与另一个表中的一列同名,则连接条件也会突然包括这些列。
select did, dname, avg_pmi
from (
    select t.*, rank() over(order by avg_pmi desc) rn
    from (
        select d.did, d.dname, avg(p.bmi) avg_pmi
        from doctor d
        inner join visit on v.did = d.did
        inner join patient p on p.pid = v.pid
        group by d.did, d.dname
    ) t
) t
where rn = 1