鉴于:
保险公司( cid ,姓名,电话,地址)
医生(做,姓名,专业,地址,电话,年龄,cid)
患者( pid ,姓名,地址,电话,年龄,性别,cid)
访问次数( vid ,确实,pid,日期,说明)
其中
cid - Insurance Company code did - doctor code pid - patient code vid - code of visit
和任务:每位医生返回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
他们都是这项任务的好方法吗?
答案 0 :(得分:3)
您的第二个查询更适合该任务,应该更好地进行优化。此外,在每个查询中,您引用Visit.age。你不应该加入专利和参考patient.age?
此外,每个人都在计算医生的独特访问,这不需要明确的陈述,因为访问永远不会重复。相反,你应该计算不同的患者(p.id)。
答案 1 :(得分:1)
第二个例子对我来说很好看。当将其编译成计划时,RDBMS将根据许多算法确定如何最好地处理它。我没有看到需要添加您在第一个版本中引入的中间步骤。
如果您非常希望确保自己拥有最佳方法,请查看生成的计划并进行比较。并查看读取,CPU时间等。
如何做到这一点取决于您使用的特定RDBMS。
答案 2 :(得分:0)
第一个查询有效,但实际上并不常见。
第二个问题是要走的路,更清楚的是发生了什么。
答案 3 :(得分: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
答案 4 :(得分: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