如何在连接两组表时解决模糊的外连接错误

时间:2015-08-18 12:46:32

标签: sql join oracle11g

我有2组表,每组包含一个标题和详细信息表。其中一个是主集,其中包含最终的记录列表,另一个集是补充集。每个明细表都有一个数量字段。我需要加入两组表并总结两组表的数量字段,但如果补充集中的记录较少,我需要显示一个null,并排除记录本身。 以下是仅显示匹配记录的数据的查询,我需要在补充集的数量字段中显示主集中的所有记录和空值。

SELECT   LTOH.txn,
           LTOH.txnno,
           LTOI.itemcode,
           SUM (LTOI.qty) AS SumOfqty,
           SUM (BTI.qty) AS SumOfqty1
    FROM      (   BTH
               INNER JOIN
                  BTI
               ON BTH.hsysid = BTI.ltohsysid)
           INNER JOIN
              (   LTOH
               INNER JOIN
                  LTOI
               ON LTOH.hsysid = LTOI.ltohsysid)
           ON     (BTI.itemcode = LTOI.itemcode)
              AND (BTH.txnno = LTOH.txnno)
              AND (BTH.txn = LTOH.txn)
GROUP BY   LTOH.txn, LTOH.txnno, LTOI.itemcode
  HAVING   ( ( (LTOH.txn) = "ABC") AND ( (LTOH.txnno) = "1"));

2 个答案:

答案 0 :(得分:0)

更改连接的顺序,使LTOI首先与已定义的BTI相关,LTOH与LTOI和BTI相关联。删除了一些不需要的()。

简单地说,连接必须按顺序发生。如果关系被定义为A - > B - > C - > D,则必须按该顺序定义连接。如果你试图去A - > B - > D - > C;您获得了显示的错误语法,因为引擎不知道如何将D连接到已定义的A,B。 SQL引擎通常按列出的顺序解析FROM子句。我通常会说,因为在Microsoft Access中,用户可以表示()表示引擎执行连接的顺序。我不确定是否有任何企业RDBMS会这样做,我通常按键的顺序定义它们以使阅读更容易......听起来像我需要尝试的东西!但是,您的()并未在from子句中添加值来表示顺序。

SELECT LTOH.txn,
  LTOH.txnno,
  LTOI.itemcode,
  SUM (LTOI.qty) AS SumOfqty,
  SUM (BTI.qty)  AS SumOfqty1
FROM BTH
INNER JOIN bti
   ON BTH.hsysid = BTI.ltohsysid
RIGHT JOIN  ltoi
   ON bti.itemcode = ltoi.itemcode
RIGHT JOIN ltoh
   ON ltoh.hsysid   = ltoi.ltohsysid
  and bth.txnno   = ltoh.txnno
  and bth.txn     = ltoh.txn
GROUP BY ltoh.txn, ltoh.txnno, ltoi.itemcode
HAVING LTOH.txn = "ABC"
  and  LTOH.txnno    = "1";

答案 1 :(得分:0)

我使用以下方法得到了预期的结果:

 SELECT   LTOHGROUP.txn,
           LTOHGROUP.txnno,
           LTOHGROUP.itemcode,
           SUM (LTOHGROUP.qty) AS SumOfqty,
           SUM (BTHGROUP.qty) AS SumOfqty1
    FROM      (SELECT   LTOH.*, LTOI.*
                 FROM      LTOH
                        INNER JOIN
                           LTOI
                        ON LTOH.hsysid = LTOI.ltohsysid) LTOHGROUP
           LEFT JOIN
              (SELECT   BTH.*, BTI.*
                 FROM      BTH
                        INNER JOIN
                           BTI
                        ON BTH.hsysid = BTI.ltohsysid) BTHGROUP
           ON     (LTOHGROUP.itemcode = BTHGROUP.itemcode)
              AND (LTOHGROUP.txnno = BTHGROUP.txnno)
              AND (LTOHGROUP.txn = BTHGROUP.txn)
GROUP BY   LTOHGROUP.txn, LTOHGROUP.txnno, LTOHGROUP.itemcode
  HAVING   ( ( (LTOHGROUP.txn) = 'ABC') AND ( (LTOHGROUP.txnno) = '1'));