2009-10-20 80 views
0

我需要做這樣的事情,以填補部分表:一個問題關於JOIN

SELECT (CASE t1.part IS NULL THEN t2.part ELSE t1.part END) AS partno, 
     t3.desc  
FROM t1 
LEFT JOIN join t2 ON [certain condition] 
LEFT JOIN t3 ON t1.part = t3.part 
      OR t2.part = t3.part 

...所以這將選擇的情況下,從T2 PARTNO價值的那部分是在T1空,則我需要從t3的描述,但是當我運行它需要永遠,永遠不會返回結果,我怎樣才能更快地做到這一點?如果我錯過了一些細節,請詢問。

這是表

alt text http://img15.imageshack.us/img15/3878/74385879.png

這是實際的程序

DELIMITER $$ 

DROP PROCEDURE IF EXISTS `getMonthDetail` $$ 
CREATE DEFINER=`root`@`%` PROCEDURE `getMonthDetail`(fechai Date, wid int) 
BEGIN 

select distinct 
ins.inventoryinid, 
(
select group_concat(concat(documents.documentname,': ', inventoryin_documents.documentno)) 
from inventoryin_documents 
left join documents on documents.documentid=inventoryin_documents.documentid 
where inventoryin_documents.inventoryinid = docin.inventoryinid 
group by inventoryin_documents.inventoryinid 
)as docin, 
trace.inventoryoutid, 
(
select group_concat(concat(documents.documentname,': ', inventoryout_documents.documentno)) 
from inventoryout_documents 
left join documents on documents.documentid=inventoryout_documents.documentid 
where inventoryout_documents.inventoryoutid = docout.inventoryoutid 
group by inventoryout_documents.inventoryoutid 
) as docout, 
outs.inventoryoutdate, 
(case when trace.partnumberp is null then indetails.partnumberp else trace.partnumberp end) as nopart, 
p.descriptionsmall, 
trace.quantity 


from 
inventoryin as ins 
left join inventoryinouttrace as trace on trace.inventoryinid = ins.inventoryinid 
left join inventoryin_documents as docin on docin.inventoryinid = ins.inventoryinid 
left join inventoryout_documents as docout on docout.inventoryoutid = trace.inventoryoutid 
left join inventoryout as outs on outs.inventoryoutid = trace.inventoryoutid 
left join inventoryindetails indetails on ins.inventoryinid = indetails.inventoryinid 
left join product as p on trace.partnumberp=p.partnumberp 

where 
((ins.inventorydate > fechai+0 and ins.inventorydate < fechai+100) 
or (outs.inventoryoutdate > fechai+0 and outs.inventoryoutdate < fechai+100)); 

END $$ 

DELIMITER ; 

,當我在查詢瀏覽器擊中解釋按鈕,它會返回一個錯誤...

回答

1

嘗試:

SELECT COALESCE(t1.part, t2.part) AS partno, 
      COALESCE(t3.desc, t4.desc)  
    FROM t1 
LEFT JOIN join t2 ON [certain condition] 
LEFT JOIN t3 ON t3.part = t1.part 
LEFT JOIN t3 AS t4 ON t4.part = t1.part 

OR的是臭名昭著的表現不佳。

+0

LOL從未想過要加入t3秒時間,這就足夠快了,謝謝 – Luiscencio 2009-10-20 17:42:51

+0

COALESCE是ANSI標準 - 可以在SQL Server或Oracle上工作,而IFNULL必須要更改。 – 2009-10-20 17:49:10

+0

如果OR的速度很慢,有沒有辦法做到WHERE更快? 其中condition1或condition3或...... – Luiscencio 2009-10-20 18:04:11

0

告訴我們數據的實際結構,並請向我們展示查詢的說明,以便我們看到它運行的原因 慢!

只有一個猜測:右邊的coumns是否有索引?

+0

好吧,讓我拍一些屏幕截圖 – Luiscencio 2009-10-20 17:17:50

0

您的某些情況應該是t2.id=t1.id並且在WHERE語句中有更多where子句。

您可能想簡化爲只有兩個選擇語句,並先查看它是否緩慢。

您可能會缺少一個有用的索引。

一旦這兩個選擇都很好,那麼你可以在case命令中添加sql,看看發生了什麼,但不要改變查詢中的其他任何內容。

然後,你可以給查詢和時間,這將有助於人們給出更好的答案。

0

好的出血明顯:我想你已經索引了你在連接中使用的字段?

1

OR子句運行緩慢,你應該考慮其中仍然利用你可能對你的T1,T2的任何索引的UNION替換它們,和T3表:

SELECT IFNULL(t1.part, t2.part) AS partno, t3.desc 
FROM t1 
LEFT JOIN t2 ON (condition here) 
LEFT JOIN t3 ON (t1.part = t3.part) 

UNION DISTINCT 

SELECT IFNULL(t1.part, t2.part) AS partno, t3.desc 
FROM t1 
LEFT JOIN t2 ON (condition here) 
LEFT JOIN t3 ON (t2.part = t3.part) 

而且,你的情況()函數,與我簡化的IFNULL()函數非常相似,最終使用臨時表。這在利用這些功能時是不可避免的。

+0

同意:每次我在連接的ON ...部分使用OR時,都需要永久完成。 – jedihawk 2009-10-20 17:20:57

+1

關於DISTINCT關鍵字是沒有必要的 - 如果它被忽略,UNION DISTINCT暗指:http://dev.mysql.com/doc/refman/5.0/en/union.html – 2009-10-20 17:27:28