2

给定:

InsuranceCompanies(cid,姓名,电话,地址)

医生(、姓名、专业、地址、电话、年龄、cid)

患者(pid、姓名、地址、电话、年龄、性别、cid)

访问次数(vid、did、pid、date、description)

在哪里

cid - 保险公司代码
做了 - 医生代码
pid - 病人代码
vid - 访问代码

和一个任务:对于每位医生,返回 20-25 岁(不同)患者的数量:

是 :

SELECT  V.did, COUNT ( V.pid ) 
FROM    (   SELECT  DISTINCT V1.did, V1.pid
            FROM    Visits V1,Patient P
            WHERE   P.pid=V1.pid and P.age >= 20 and  P.age <=25 ) AS V 
GROUP BY    V.did

相当于 :

SELECT  V.did, COUNT (DISTINCT V.pid ) 
FROM    Visits V,Patient P
WHERE   P.pid=V.pid and P.age >= 20 and  P.age <=25
GROUP BY    V.did

它们都是完成任务的好方法吗?

4

5 回答 5

3

您的第二个查询更适合该任务,并且应该更好地优化。此外,在每个查询中,您都引用了 Visit.age。您不应该加入专利和参考患者年龄吗?

此外,在每次您计算医生的唯一访问时,这不需要不同的声明,因为访问永远不会重复。相反,您应该计算不同的患者 (p.id)。

于 2012-04-24T20:27:33.157 回答
1

第二个例子对我来说很好。当这被编译成一个计划时,RDBMS 会从许多算法中找出最好的方法。我认为不需要添加您在第一个版本中介绍的中间步骤。

如果您非常渴望确保自己拥有最佳方法,请查看生成的计划并进行比较。并查看读取、CPU 时间等。

如何做到这一点取决于您使用的特定 RDBMS。

于 2012-04-24T20:27:51.230 回答
0

第一个查询有效,但不是真正常见的做法。

第二个查询是要走的路,更清楚会发生什么。

于 2012-04-24T20:26:56.323 回答
0

这是两个不同的查询,可能

1)您正在计算患者和医生之间的不同访问次数,这意味着如果患者两次看医生,您将不会计算它

2)您只是计算医生的访问次数,如果同一患者多次访问,则将被计算两次

所以对于这项任务,1)是正确的答案,但 2)看起来更好

SELECT  V.did, COUNT ( V.id ) 
FROM    (   SELECT  DISTINCT V1.did, V1.pid
            FROM    Visits V1
            WHERE V1.age >= 20 and  V1.age <=25 ) AS V  
GROUP BY    V.did

可以更好地写为

SELECT  V.did, COUNT ( V.pid ) ### change here
FROM    Visits, ### your joins
            WHERE V1.age >= 20 and  V1.age <=25 
GROUP BY    V.did
于 2012-04-24T20:28:04.727 回答
0

您将不得不使用左连接,因为它说for each doctor并且您没有显示没有就诊的医生0

select d.did, count(distinct p.pid) from doctor d
left join visits v on d.did = v.did
join patients p on v.pid = p.pid
where p.age between 20 and 25
group by d.did
于 2012-04-24T20:38:06.013 回答