多零件标识符不能在左外部联接上绑定

时间:2019-01-02 17:37:18

标签: sql sql-server sql-server-2014

我有以下查询,我试图向左外部连接添加条件,但是别名表(B)出错,因为它无法绑定。

如果我将条件添加到WHERE条件中,它将起作用,但是我认为这将过滤掉比我想要的更多的行,因此我确实希望将其包含在外部联接中。

SELECT  A.BUSINESS_UNIT, D.DESCR, 
(CONVERT(CHAR(10),A.PO_DT,121)), A.PO_ID, A.VENDOR_ID,
 B.LINE_NBR, B.INV_ITEM_ID, E.DESCR, B.ITM_ID_VNDR, B.CATEGORY_ID, B.UNIT_OF_MEASURE,
 B.MFG_ID, B.MFG_ITM_ID, C.MERCHANDISE_AMT, C.QTY_PO, C.MERCH_AMT_BSE, C.ACCOUNT,
 E.CATEGORY_ID, F.DESCR60, E.ITEM_FIELD_C10_A, E.ITEM_FIELD_C10_B, H.INVOICE_ID, H.INVOICE_DT, H.VOUCHER_ID
  FROM  PS_PO_HDR A 

  LEFT OUTER JOIN PS_VOUCHER_LINE G ON A.PO_ID = G.PO_ID AND A.BUSINESS_UNIT = G.BUSINESS_UNIT AND G.LINE_NBR = B.LINE_NBR
  LEFT OUTER JOIN PS_VOUCHER H ON G.VOUCHER_ID = H.VOUCHER_ID AND G.BUSINESS_UNIT = H.BUSINESS_UNIT

  ,PS_PO_LINE B, PS_PO_LINE_DISTRIB C, PS_BUS_UNIT_TBL_FS D,
  (PS_MASTER_ITEM_TBL E 

   LEFT OUTER JOIN  PS_ITM_CAT_TBL F ON  E.SETID = F.SETID AND F.CATEGORY_ID = E.CATEGORY_ID )


    WHERE ( A.BUSINESS_UNIT = B.BUSINESS_UNIT 
     AND A.PO_ID = B.PO_ID 
     AND B.BUSINESS_UNIT = C.BUSINESS_UNIT 
     AND B.PO_ID = C.PO_ID 
     AND B.LINE_NBR = C.LINE_NBR 
     AND A.PO_DT BETWEEN '2018-12-05' AND '2018-12-12' 
     AND A.BUSINESS_UNIT = D.BUSINESS_UNIT 
     AND E.INV_ITEM_ID = B.INV_ITEM_ID 
     AND F.EFFDT = 
        (SELECT MAX(F_ED.EFFDT) FROM PS_ITM_CAT_TBL F_ED 
        WHERE F.SETID = F_ED.SETID 
          AND F.CATEGORY_TYPE = F_ED.CATEGORY_TYPE 
          AND F.CATEGORY_CD = F_ED.CATEGORY_CD 
          AND F.CATEGORY_ID = F_ED.CATEGORY_ID 
          AND F_ED.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE(),121), 1, 10)))

LEFT OUTER JOIN PS_VOUCHER_LINE G ON A.PO_ID = G.PO_ID AND A.BUSINESS_UNIT = G.BUSINESS_UNIT **AND G.LINE_NBR = B.LINE_NBR**

错误:

  

无法绑定多部分标识符“ B.LINE_NBR”。

我相信这是因为在此联接之后才声明PS_PO_LINE B表。如果将联接移动到FROM部分的底部,那么我将在PS_PO_HDR A上仍然遇到绑定错误,仍然在PS_PO_LINE B上,因此我不确定如何避免使用WHERE部分。感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

问题在于您正在混合使用联接语法。 Don't use old style joins.

如果重新格式化代码,则会看到问题。

SELECT
   A.BUSINESS_UNIT,
   D.DESCR,
   (
      CONVERT(CHAR(10), A.PO_DT, 121)
   ),
   A.PO_ID,
   A.VENDOR_ID,
   B.LINE_NBR,      
   B.INV_ITEM_ID,
   E.DESCR,
   B.ITM_ID_VNDR,
   B.CATEGORY_ID,
   B.UNIT_OF_MEASURE,
   B.MFG_ID,
   B.MFG_ITM_ID,
   C.MERCHANDISE_AMT,
   C.QTY_PO,
   C.MERCH_AMT_BSE,
   C.ACCOUNT,
   E.CATEGORY_ID,
   F.DESCR60,
   E.ITEM_FIELD_C10_A,
   E.ITEM_FIELD_C10_B,
   H.INVOICE_ID,
   H.INVOICE_DT,
   H.VOUCHER_ID 
FROM
   PS_PO_HDR A 
   LEFT OUTER JOIN
      PS_VOUCHER_LINE G 
      ON A.PO_ID = G.PO_ID 
      AND A.BUSINESS_UNIT = G.BUSINESS_UNIT 
      AND G.LINE_NBR = B.LINE_NBR 
   LEFT OUTER JOIN
      PS_VOUCHER H 
      ON G.VOUCHER_ID = H.VOUCHER_ID 
      AND G.BUSINESS_UNIT = H.BUSINESS_UNIT,
      PS_PO_LINE B,
      PS_PO_LINE_DISTRIB C,
      PS_BUS_UNIT_TBL_FS D,
      (
         PS_MASTER_ITEM_TBL E 
         LEFT OUTER JOIN
            PS_ITM_CAT_TBL F 
            ON E.SETID = F.SETID 
            AND F.CATEGORY_ID = E.CATEGORY_ID 
      )
WHERE
   (
      A.BUSINESS_UNIT = B.BUSINESS_UNIT 
      AND A.PO_ID = B.PO_ID 
      AND B.BUSINESS_UNIT = C.BUSINESS_UNIT 
      AND B.PO_ID = C.PO_ID 
      AND B.LINE_NBR = C.LINE_NBR 
      AND A.PO_DT BETWEEN '2018-12-05' AND '2018-12-12' 
      AND A.BUSINESS_UNIT = D.BUSINESS_UNIT 
      AND E.INV_ITEM_ID = B.INV_ITEM_ID 
      AND F.EFFDT = 
      (
         SELECT
            MAX(F_ED.EFFDT) 
         FROM
            PS_ITM_CAT_TBL F_ED 
         WHERE
            F.SETID = F_ED.SETID 
            AND F.CATEGORY_TYPE = F_ED.CATEGORY_TYPE 
            AND F.CATEGORY_CD = F_ED.CATEGORY_CD 
            AND F.CATEGORY_ID = F_ED.CATEGORY_ID 
            AND F_ED.EFFDT <= SUBSTRING(CONVERT(CHAR, GETDATE(), 121), 1, 10)
      )
   )
   LEFT OUTER JOIN
      PS_VOUCHER_LINE G 
      ON A.PO_ID = G.PO_ID 
      AND A.BUSINESS_UNIT = G.BUSINESS_UNIT **
      AND G.LINE_NBR = B.LINE_NBR*

您拥有的代码的最底端:

   LEFT OUTER JOIN
      PS_VOUCHER_LINE G 
      ON A.PO_ID = G.PO_ID 
      AND A.BUSINESS_UNIT = G.BUSINESS_UNIT **
      AND G.LINE_NBR = B.LINE_NBR*

假设*实际上不在您的代码中(因为这也会导致问题),JOIN语句在WHERE子句之前 。这是WHERE子句的之后。您需要移动它。

将所有内容更改为显式联接语法,并删除了一些假逗号和不必要的括号后,此处便是您想要的选项。只需检查我有评论的JOIN子句。

SELECT
   A.BUSINESS_UNIT,
   D.DESCR,
   (
      CONVERT(CHAR(10), A.PO_DT, 121)
   ),
   A.PO_ID,
   A.VENDOR_ID,
   B.LINE_NBR,      
   B.INV_ITEM_ID,
   E.DESCR,
   B.ITM_ID_VNDR,
   B.CATEGORY_ID,
   B.UNIT_OF_MEASURE,
   B.MFG_ID,
   B.MFG_ITM_ID,
   C.MERCHANDISE_AMT,
   C.QTY_PO,
   C.MERCH_AMT_BSE,
   C.ACCOUNT,
   E.CATEGORY_ID,
   F.DESCR60,
   E.ITEM_FIELD_C10_A,
   E.ITEM_FIELD_C10_B,
   H.INVOICE_ID,
   H.INVOICE_DT,
   H.VOUCHER_ID 
FROM
   PS_PO_HDR A 
    LEFT OUTER JOIN
      PS_VOUCHER_LINE G 
      ON A.PO_ID = G.PO_ID 
      AND A.BUSINESS_UNIT = G.BUSINESS_UNIT 
      AND G.LINE_NBR = B.LINE_NBR 
    LEFT OUTER JOIN
      PS_VOUCHER H 
      ON G.VOUCHER_ID = H.VOUCHER_ID 
      AND G.BUSINESS_UNIT = H.BUSINESS_UNIT

    /*BEGIN code taken from where clause */
    LEFT OUTER JOIN
      PS_PO_LINE B  
      ON A.BUSINESS_UNIT = B.BUSINESS_UNIT 
      AND A.PO_ID = B.PO_ID 
    LEFT OUTER JOIN
      PS_PO_LINE_DISTRIB C
      ON B.BUSINESS_UNIT = C.BUSINESS_UNIT 
      AND B.PO_ID = C.PO_ID 
      AND B.LINE_NBR = C.LINE_NBR 
    LEFT OUTER JOIN
      PS_BUS_UNIT_TBL_FS D
      ON A.BUSINESS_UNIT = D.BUSINESS_UNIT 
    LEFT OUTER JOIN
      PS_MASTER_ITEM_TBL E
      ON  E.INV_ITEM_ID = B.INV_ITEM_ID 
      /*END code taken from where clause */

    LEFT OUTER JOIN
      PS_ITM_CAT_TBL F 
      ON E.SETID = F.SETID 
      AND F.CATEGORY_ID = E.CATEGORY_ID 
    LEFT OUTER JOIN
      PS_VOUCHER_LINE G 
      ON A.PO_ID = G.PO_ID 
      AND A.BUSINESS_UNIT = G.BUSINESS_UNIT 
      AND G.LINE_NBR = B.LINE_NBR
WHERE

      A.PO_DT BETWEEN '2018-12-05' AND '2018-12-12' 
      AND F.EFFDT = 
      (
         SELECT
            MAX(F_ED.EFFDT) 
         FROM
            PS_ITM_CAT_TBL F_ED 
         WHERE
            F.SETID = F_ED.SETID 
            AND F.CATEGORY_TYPE = F_ED.CATEGORY_TYPE 
            AND F.CATEGORY_CD = F_ED.CATEGORY_CD 
            AND F.CATEGORY_ID = F_ED.CATEGORY_ID 
            AND F_ED.EFFDT <= SUBSTRING(CONVERT(CHAR, GETDATE(), 121), 1, 10)
      )