2009-10-20 82 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