2010-01-26 65 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的最佳條目。