SQL查询,如何处理复杂的查询?

时间:2012-05-01 17:12:45

标签: sql

我在本学期学习DBMS课程,我想确保我做好进步并练习好思维,我自己处理查询的方法有点像分而治之 - 我将查询拆分为子查询并制作它们视图,然后使用这些视图来简单地收集我需要的信息,一般来说,这是一个好方法吗?

有什么改变?

你自己的做法是什么?如果你认为它比我的好,为什么?

示例:

GIVEN:DB:http://sqlfiddle.com/#!2/cdd98/1

  

(Q7)找到访问过与保险公司相关的所有骨科医生(专科)的患者。

CREATE VIEW Orthos AS
SELECT  d.cid,d.did
FROM Doctors d
WHERE d.speciality='Orthopedist';

CREATE VIEW OrthosPerInc AS
SELECT  o.cid, COUNT(o.did) as countd4i
FROM Orthos o
GROUP BY o.cid;

CREATE VIEW OrthoVisitsPerPat AS
SELECT v.pid,COUNT(o.did) as countv4d
FROM Orthos o,Visits v,Doctors d
WHERE o.did=v.did and d.did=o.did
GROUP BY v.pid,d.cid;

SELECT  p.pname,p.pid,p.cid
FROM  OrthoVisitsPerPat v, OrthosPerInc i,Patient p
WHERE i.countd4i = v.countv4d and p.pid=v.pid and p.cid=i.cid

2 个答案:

答案 0 :(得分:1)

这实际上取决于数据库。某些数据库(例如MySQL)在优化使用视图的查询方面非常糟糕。其他人并不是那么糟糕。

但是你将查询分解成碎片然后将它们组合成更复杂的查询的策略是一个很好的策略。我会(通常)最终制作一个组合部分的大型查询。

答案 1 :(得分:1)

不要为此使用视图,使用派生表,临时表或CTES。视图是数据库中的permananent对象,过度使用它们是一个真正的问题,尤其是当您开始编写调用其他视图的视图时。我们几乎失去了一个价值数百万美元的客户端,因为开发人员错误地认为这些观点是一件好事,这使得系统变得如此之慢,以至于数据被加载后无法使用。初学者永远不需要写一个视图。

学会使用真正的联接 - 它将使你更好地支持你。

然而,是的,可以将复杂的东西分解成块。只是不要通过使用视图来做到这一点。

暗示加入是一种非常糟糕的技术,它们已经过时了20年,并且没有理由在2012年使用它们。承诺自己永远不会再使用它们。不要学习糟糕的技巧,学习正确的技巧。

我会做的事情(未经测试):

SELECT  MDByPatient.pname,MDByPatient.pid,MDByPatient.cid
FROM 
    (
    SELECT   p.pname,p.pid,p.cid, count(v.did) as CountMDByPatient
    FROM  Patient p  
    INNER JOIN (SELECT DISTINCT v.pid, v.did FROM Visits) v
        ON p.pid = v.pid
    INNER JOIN Doctors d 
        ON d.did = v.did and p.cid = d.cid
    WHERE d.speciality='Orthopedist' 
    GROUP BY p.pname,p.pid,p.cid
    ) MDByPatient
INNER JOIN 
    (
    SELECT cid, count(did)as CountMDByIns
    FROM Doctors 
    WHERE d.speciality='Orthopedist' 
    GROUP BY cid
    ) MDByInsurance
        ON  MDByPatient.cid = MDByInsurance.cid
where MDByPatient.CountMDByPatient = MDByInsurance.CountMDByIns

你看,它仍然被分成几块,一个用于获得保险公司的骨科医生数量,另一个用于获得保险公司和人员访问过的人的骨科医生数量。我进一步做了一个'SELECT DISTINCT v.pid,v.did FROM Visits',因为我不希望医生的数量不正确,因为我不止一次去过同一个人。