2010-01-26 48 views
0

删除冗余我有4个表如何优化或以下查询

Table1 (employee) 
id   name 
-------------------- 
1   a 
2   b 

Table2 (appointment) 
id table1id table3id table4id sdate edate  typeid 
----------------------------------------------------------------------------------- 
1  1    1   1  1/1/09 NULL  100 
2  2    2   1  1/1/09 NULL  101 


Table3 (title) 
id  name 
--------------- 
1  worker1 
2  worker2 
3  Assistant 
4  Manager 

Table4 (Department names) 
id  name 
------------------- 
1  Logistics 
2  ABC 
3  XYZ 

Type 
id  name 
---------------- 
100  w (primary) 
101  e (secondary) 
102  r (other-primary) 
103  t (.....) 
104  y (....) 

要避免的DUP我写查询作为

Select id, name, title, dept 
FROM table1 a 
INNER JOIN table2 b ON a.id = b.table1id 
INNER JOIN table3 c ON b.table3id = c.id 
INNER JOIN table4 d ON d.id = b.table4id 
WHERE typeid = 
     (
      SELECT min(type_id) /* i want primary type appointments */ 
      FROM table2 
      WHERE sdate < getdate() and (edate > getdate() or edate IS NULL) 
      AND sdate = (select max(sdate) from table2 where table1id = a.id) 
      AND typeid in (100, 102) 
     ) 
AND b.sdate < getdate() and (b.edate > getdate() or b.edate IS NULL) 
AND b.sdate = (select max(sdate) from table2 where table1id = a.id) 

/* last two i have to repeat again to remove dupes */ 

有没有一种方法,我可以使用相同的条件下减少两倍并查询它只指定一次或任何其他更好的方式? AND typeid in(100,102)

+3

哎呀...你有表的别名定义,但你不外JOIN使用它们语法 – 2010-01-26 23:03:54

+1

如果你可以说出你想要回答什么问题,那会有所帮助。 – Sam 2010-01-26 23:04:19

+1

如果您使用真实表和列名称而不是像'INNER JOIN table4 d ON d.id = b.table4id'那样理解您的查询会容易得多。你能解释你的查询应该做什么吗? – 2010-01-26 23:04:27

回答

0

我用同样的查询,并将其工作速度快,我没有发现任何其他的方式来优化它

0

会是这样的改进,在连接中使用子查询来获得你想要的数字吗?

Select id, name, title, dept 
FROM table1 a 
INNER JOIN table2 b ON a.id = b.table1id 
INNER JOIN table3 c ON b.table3id = c.id 
INNER JOIN table4 d ON d.id = b.table4id 
INNER JOIN (select max(sdate) from table2 group by table1id) new1 ON new1.table1id = a.id 
WHERE typeid = 
    (
     SELECT min(type_id) /* i want primary type appointments */ 
     FROM table2 
     WHERE sdate < getdate() and (edate > getdate() or edate IS NULL) 
     AND sdate = (select max(sdate) from table2 where table1id = a.id) 
     AND typeid in (100, 102) 
    ) 
AND b.sdate < getdate() and (b.edate > getdate() or b.edate IS NULL) 
AND b.sdate = new1.sdate 

您也可以尝试查看GROUP BY的HAVING子句。我想你将能够做这样的事情:

Select id, name, title, dept 
FROM table1 a 
INNER JOIN table2 b ON a.id = b.table1id 
INNER JOIN table3 c ON b.table3id = c.id 
INNER JOIN table4 d ON d.id = b.table4id 
WHERE b.sdate < getdate() and (b.edate > getdate() or b.edate IS NULL) 
AND typeid in (100, 102) 
GROUP BY id, name, title, dept 
HAVING b.sdate = max(sdate) 
    AND typeid = min(type_id) 

然而上述可能拉动整个列表中的最小值和最大值,不是每个a.id.我忘了你是否可以在max中使用分区来指定最大化的内容,或者如果我在那里考虑Oracle。如果没有,你可以使用一个子查询来获得每个a.id的最佳条目。