代码之家  ›  专栏  ›  技术社区  ›  Luiscencio

关于加入的问题

  •  0
  • Luiscencio  · 技术社区  · 15 年前

    我需要这样做来填写零件表:

    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
    

    …因此,如果T1中的partno为空,那么这将从t2中选择partno的值,然后我需要从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 ;
    

    当我点击查询浏览器中的解释按钮时,它会返回一个错误…

    5 回复  |  直到 15 年前
        1
  •  1
  •   OMG Ponies    15 年前

    尝试:

       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
    

    或因性能不佳而臭名昭著。

        2
  •  1
  •   Corey Ballou    15 年前

    或子句运行缓慢,您应该考虑用一个联合来替换它们,该联合仍然使用T1、T2和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)
    

    而且,您的case()函数,与我的简化ifnull()函数非常相似,最终使用了一个临时表。当使用这些功能时,这是不可避免的。

        3
  •  0
  •   theomega    15 年前

    请告诉我们数据的实际结构 向我们展示查询的解释,以便我们了解为什么它运行缓慢!

    只是猜测一下: 右边有索引吗?

        4
  •  0
  •   James Black    15 年前

    你的某些情况应该是 t2.id=t1.id 并且在WHERE语句中有更多的WHERE子句。

    您可能希望将其简化为只有两个select语句,并首先查看它是否很慢。

    您可能缺少一个有帮助的索引。

    一旦两个选择都好了,就可以添加 case 命令到SQL,查看发生了什么,但不要更改查询中的任何其他内容。

    然后,您可以给出查询和时间,这将帮助人们给出更好的答案。

        5
  •  0
  •   Peter Booster    15 年前

    显然,流血是可以的:我想您已经为连接中使用的字段编制了索引了吧?