1

I've inherited some <cough>ugly</cough> code that contains a rather unwieldy SQL statement that hits an Informix database. This code computes various parts of the SQL, and does lots of string concatenation, but I had it spit out what it actually sends to Informix and tried using that in my SQL query tool. It is functional when it runs on the server, but when I try running it in FlySpeed SQL (which is an "approved" tool for use at the office), it complains about outer as an unknown keyword. Googling got me nowhere, so I guessed this was an Informix shortcut for LEFT OUTER JOIN, but replacing it with that did nothing to fix the problem, so I'm guessing it's just a bug in FlySpeed.

The SQL is completely unformatted, which I'm guessing is part of what is tripping up FlySpeed.

SELECT A.CRSPD_SETID, A.CRSPD_CUST_ID, F.ST_ID_NUM as STMT_NBR, F.ST_DT, A.BUSINESS_UNIT, H.ASOF_DT, H.DUE_DT, A.ITEM, H.CONTRACT_NUM, D.DESCR as ENTRY_TYPE_DESCR, G.DESCR as ENTRY_REASON_DESCR, SUM(A.BAL_AMT) as ORIG_BAL_AMT, SUM(H.BAL_AMT), C.NAME1, B.ADDRESS1, B.ADDRESS2, B.ADDRESS3, B.ADDRESS4, B.CITY, B.STATE, B.POSTAL, A.BAL_CURRENCY, A.CUST_ID, A.ENTRY_TYPE as ORIG_ENTRY_TYPE, CASE WHEN A.ENTRY_TYPE = 'PY' OR A.ENTRY_TYPE = 'BGB' THEN 'AA' || substr(A.ENTRY_TYPE,1,3) ELSE  substr(A.ENTRY_TYPE,1,3) END, A.ENTRY_REASON as ORIG_ENTRY_REASON, C.CUSTOMER_TYPE, K.AR_LVL, H.ORDER_NO FROM PS_STMT_CUST_DTL A, PS_CUST_ADDRESS B, PS_CUSTOMER C, PS_SET_CNTRL_REC E, PS_STMT_CUST F, PS_ENTRY_TYPE_TBL D, PS_ENTRY_REASN_TBL G, outer PS_ITEM H, outer PS_BI_TYPE K WHERE A.ADDRESS_SEQ_NUM = B.ADDRESS_SEQ_NUM AND B.EFFDT = (SELECT MAX(B_ED.EFFDT) FROM PS_CUST_ADDRESS B_ED Where B.SETID = B_ED.SETID AND B.CUST_ID = B_ED.CUST_ID AND B.ADDRESS_SEQ_NUM = B_ED.ADDRESS_SEQ_NUM AND B_ED.EFFDT <=  '06/19/2013') AND A.CRSPD_SETID = B.SETID AND A.CRSPD_CUST_ID = B.CUST_ID AND B.SETID = C.SETID AND B.CUST_ID = C.CUST_ID AND B.ADDRESS_SEQ_NUM = C.ADDRESS_SEQ_NUM AND G.ENTRY_TYPE = A.ENTRY_TYPE AND G.ENTRY_REASON = A.ENTRY_REASON AND G.SETID = E.SETID AND G.SETID = D.SETID AND G.ENTRY_TYPE = D.ENTRY_TYPE AND E.SETCNTRLVALUE = A.BUSINESS_UNIT AND E.RECNAME = 'ENTRY_TYPE_TBL' AND A.CRSPD_SETID = F.CRSPD_SETID AND A.CRSPD_CUST_ID = F.CRSPD_CUST_ID AND A.ST_ID_NUM = F.ST_ID_NUM AND A.BUSINESS_UNIT = H.BUSINESS_UNIT AND A.CUST_ID = H.CUST_ID AND A.ITEM = H.ITEM AND A.ITEM_LINE = H.ITEM_LINE AND substr(A.ENTRY_TYPE,1,3) = K.BILL_TYPE_ID AND K.SETID = 'SPN' AND K.EFFDT = (SELECT MAX(C_ED.EFFDT) FROM PS_BI_TYPE C_ED WHERE K.SETID = C_ED.SETID AND K.BILL_TYPE_ID = C_ED.BILL_TYPE_ID AND C_ED.EFFDT <=  '06/19/2013') AND K.EFF_STATUS = 'A' AND A.CRSPD_CUST_ID =  '000331' AND A.CRSPD_SETID = 'SPN' AND F.ST_DT = '' AND F.ST_ID_NUM = '' GROUP BY A.CRSPD_SETID, A.CRSPD_CUST_ID, F.ST_ID_NUM, F.ST_DT, A.BUSINESS_UNIT ,H.ASOF_DT, H.DUE_DT, A.ITEM, H.CONTRACT_NUM, D.DESCR, G.DESCR, C.NAME1 ,B.ADDRESS1, B.ADDRESS2, B.ADDRESS3, B.ADDRESS4, B.CITY, B.STATE ,B.POSTAL, A.BAL_CURRENCY, A.CUST_ID, A.ENTRY_TYPE ,25, A.ENTRY_REASON, C.CUSTOMER_TYPE, K.AR_LVL, H.ORDER_NO UNION ALL  SELECT A.CRSPD_SETID, A.CRSPD_CUST_ID, F.ST_ID_NUM as STMT_NBR, F.ST_DT, A.BUSINESS_UNIT, H.ASOF_DT, H.DUE_DT, A.ITEM, H.CONTRACT_NUM, D.DESCR as ENTRY_TYPE_DESCR, G.DESCR as ENTRY_REASON_DESCR, SUM(A.BAL_AMT) as ORIG_BAL_AMT, SUM(H.BAL_AMT), C.NAME1, B.ADDRESS1, B.ADDRESS2, B.ADDRESS3, B.ADDRESS4, B.CITY, B.STATE, B.POSTAL, A.BAL_CURRENCY, A.CUST_ID, A.ENTRY_TYPE as ORIG_ENTRY_TYPE, CASE WHEN A.ENTRY_TYPE = 'PY' OR A.ENTRY_TYPE = 'BGB' THEN 'AA' || substr(A.ENTRY_TYPE,1,3) ELSE  substr(A.ENTRY_TYPE,1,3) END, A.ENTRY_REASON as ORIG_ENTRY_REASON, C.CUSTOMER_TYPE, K.AR_LVL, H.ORDER_NO FROM PS_AR_STMT_CUSDT_H A, PS_CUST_ADDRESS B, PS_CUSTOMER C, PS_SET_CNTRL_REC E, PS_AR_STMT_CUST_H F, PS_ENTRY_TYPE_TBL D, PS_ENTRY_REASN_TBL G, outer PS_AR_ITEM_H H, outer PS_BI_TYPE K WHERE A.ADDRESS_SEQ_NUM = B.ADDRESS_SEQ_NUM AND B.EFFDT = (SELECT MAX(B_ED.EFFDT) FROM PS_CUST_ADDRESS B_ED Where B.SETID = B_ED.SETID AND B.CUST_ID = B_ED.CUST_ID AND B.ADDRESS_SEQ_NUM = B_ED.ADDRESS_SEQ_NUM AND B_ED.EFFDT <=  '06/19/2013') AND A.CRSPD_SETID = B.SETID AND A.CRSPD_CUST_ID = B.CUST_ID AND B.SETID = C.SETID AND B.CUST_ID = C.CUST_ID AND B.ADDRESS_SEQ_NUM = C.ADDRESS_SEQ_NUM AND G.ENTRY_TYPE = A.ENTRY_TYPE AND G.ENTRY_REASON = A.ENTRY_REASON AND G.SETID = E.SETID AND G.SETID = D.SETID AND G.ENTRY_TYPE = D.ENTRY_TYPE AND E.SETCNTRLVALUE = A.BUSINESS_UNIT AND E.RECNAME = 'ENTRY_TYPE_TBL' AND A.CRSPD_SETID = F.CRSPD_SETID AND A.CRSPD_CUST_ID = F.CRSPD_CUST_ID AND A.ST_ID_NUM = F.ST_ID_NUM AND A.BUSINESS_UNIT = H.BUSINESS_UNIT AND A.CUST_ID = H.CUST_ID AND A.ITEM = H.ITEM AND A.ITEM_LINE = H.ITEM_LINE AND substr(A.ENTRY_TYPE,1,3) = K.BILL_TYPE_ID AND K.SETID = 'SPN' AND K.EFFDT = (SELECT MAX(C_ED.EFFDT) FROM PS_BI_TYPE C_ED WHERE K.SETID = C_ED.SETID AND K.BILL_TYPE_ID = C_ED.BILL_TYPE_ID AND C_ED.EFFDT <=  '06/19/2013') AND K.EFF_STATUS = 'A' AND A.CRSPD_CUST_ID =  '000331' AND A.CRSPD_SETID = 'SPN' AND F.ST_DT = '' AND F.ST_ID_NUM = '' GROUP BY A.CRSPD_SETID, A.CRSPD_CUST_ID, F.ST_ID_NUM, F.ST_DT, A.BUSINESS_UNIT ,H.ASOF_DT, H.DUE_DT, A.ITEM, H.CONTRACT_NUM, D.DESCR, G.DESCR, C.NAME1 ,B.ADDRESS1, B.ADDRESS2, B.ADDRESS3, B.ADDRESS4, B.CITY, B.STATE ,B.POSTAL, A.BAL_CURRENCY, A.CUST_ID, A.ENTRY_TYPE ,25, A.ENTRY_REASON, C.CUSTOMER_TYPE, K.AR_LVL, H.ORDER_NO ORDER BY 2,3,4,25,8,11,24

Am I correct that OUTER is just shorthand (maybe Informix-flavored shorthand) for LEFT OUTER JOIN?

UPDATE: I've found here that Informix did in fact use OUTER, but I've yet to find any explanation of just how. Obviously search results overwhelmingly favor things containing the normal syntax. Even this very useful RDBMS comparison contains almost nothing about Informix.

Here's the formatted SQL (sorry about the size!):

SELECT A.CRSPD_SETID,
       A.CRSPD_CUST_ID,
       F.ST_ID_NUM AS STMT_NBR,
       F.ST_DT,
       A.BUSINESS_UNIT,
       H.ASOF_DT,
       H.DUE_DT,
       A.ITEM,
       H.CONTRACT_NUM,
       D.DESCR AS ENTRY_TYPE_DESCR,
       G.DESCR AS ENTRY_REASON_DESCR,
       SUM(A.BAL_AMT) AS ORIG_BAL_AMT,
       SUM(H.BAL_AMT),
       C.NAME1,
       B.ADDRESS1,
       B.ADDRESS2,
       B.ADDRESS3,
       B.ADDRESS4,
       B.CITY,
       B.STATE,
       B.POSTAL,
       A.BAL_CURRENCY,
       A.CUST_ID,
       A.ENTRY_TYPE AS ORIG_ENTRY_TYPE,
       CASE
           WHEN A.ENTRY_TYPE = 'PY'
                OR A.ENTRY_TYPE = 'BGB' THEN 'AA' || substr(A.ENTRY_TYPE,1,3)
           ELSE substr(A.ENTRY_TYPE,1,3)
       END,
       A.ENTRY_REASON AS ORIG_ENTRY_REASON,
       C.CUSTOMER_TYPE,
       K.AR_LVL,
       H.ORDER_NO
FROM PS_STMT_CUST_DTL A,
     PS_CUST_ADDRESS B,
     PS_CUSTOMER C,
     PS_SET_CNTRL_REC E,
     PS_STMT_CUST F,
     PS_ENTRY_TYPE_TBL D,
     PS_ENTRY_REASN_TBL G,
     OUTER PS_ITEM H,
           OUTER PS_BI_TYPE K
WHERE A.ADDRESS_SEQ_NUM = B.ADDRESS_SEQ_NUM
  AND B.EFFDT =
    (SELECT MAX(B_ED.EFFDT)
     FROM PS_CUST_ADDRESS B_ED
     WHERE B.SETID = B_ED.SETID
       AND B.CUST_ID = B_ED.CUST_ID
       AND B.ADDRESS_SEQ_NUM = B_ED.ADDRESS_SEQ_NUM
       AND B_ED.EFFDT <= '06/19/2013')
  AND A.CRSPD_SETID = B.SETID
  AND A.CRSPD_CUST_ID = B.CUST_ID
  AND B.SETID = C.SETID
  AND B.CUST_ID = C.CUST_ID
  AND B.ADDRESS_SEQ_NUM = C.ADDRESS_SEQ_NUM
  AND G.ENTRY_TYPE = A.ENTRY_TYPE
  AND G.ENTRY_REASON = A.ENTRY_REASON
  AND G.SETID = E.SETID
  AND G.SETID = D.SETID
  AND G.ENTRY_TYPE = D.ENTRY_TYPE
  AND E.SETCNTRLVALUE = A.BUSINESS_UNIT
  AND E.RECNAME = 'ENTRY_TYPE_TBL'
  AND A.CRSPD_SETID = F.CRSPD_SETID
  AND A.CRSPD_CUST_ID = F.CRSPD_CUST_ID
  AND A.ST_ID_NUM = F.ST_ID_NUM
  AND A.BUSINESS_UNIT = H.BUSINESS_UNIT
  AND A.CUST_ID = H.CUST_ID
  AND A.ITEM = H.ITEM
  AND A.ITEM_LINE = H.ITEM_LINE
  AND substr(A.ENTRY_TYPE,1,3) = K.BILL_TYPE_ID
  AND K.SETID = 'SPN'
  AND K.EFFDT =
    (SELECT MAX(C_ED.EFFDT)
     FROM PS_BI_TYPE C_ED
     WHERE K.SETID = C_ED.SETID
       AND K.BILL_TYPE_ID = C_ED.BILL_TYPE_ID
       AND C_ED.EFFDT <= '06/19/2013')
  AND K.EFF_STATUS = 'A'
  AND A.CRSPD_CUST_ID = '000331'
  AND A.CRSPD_SETID = 'SPN'
  AND F.ST_DT = ''
  AND F.ST_ID_NUM = ''
GROUP BY A.CRSPD_SETID,
         A.CRSPD_CUST_ID,
         F.ST_ID_NUM,
         F.ST_DT,
         A.BUSINESS_UNIT ,
         H.ASOF_DT,
         H.DUE_DT,
         A.ITEM,
         H.CONTRACT_NUM,
         D.DESCR,
         G.DESCR,
         C.NAME1 ,
         B.ADDRESS1,
         B.ADDRESS2,
         B.ADDRESS3,
         B.ADDRESS4,
         B.CITY,
         B.STATE ,
         B.POSTAL,
         A.BAL_CURRENCY,
         A.CUST_ID,
         A.ENTRY_TYPE ,
         25,
         A.ENTRY_REASON,
         C.CUSTOMER_TYPE,
         K.AR_LVL,
         H.ORDER_NO
UNION ALL
SELECT A.CRSPD_SETID,
       A.CRSPD_CUST_ID,
       F.ST_ID_NUM AS STMT_NBR,
       F.ST_DT,
       A.BUSINESS_UNIT,
       H.ASOF_DT,
       H.DUE_DT,
       A.ITEM,
       H.CONTRACT_NUM,
       D.DESCR AS ENTRY_TYPE_DESCR,
       G.DESCR AS ENTRY_REASON_DESCR,
       SUM(A.BAL_AMT) AS ORIG_BAL_AMT,
       SUM(H.BAL_AMT),
       C.NAME1,
       B.ADDRESS1,
       B.ADDRESS2,
       B.ADDRESS3,
       B.ADDRESS4,
       B.CITY,
       B.STATE,
       B.POSTAL,
       A.BAL_CURRENCY,
       A.CUST_ID,
       A.ENTRY_TYPE AS ORIG_ENTRY_TYPE,
       CASE
           WHEN A.ENTRY_TYPE = 'PY'
                OR A.ENTRY_TYPE = 'BGB' THEN 'AA' || substr(A.ENTRY_TYPE,1,3)
           ELSE substr(A.ENTRY_TYPE,1,3)
       END,
       A.ENTRY_REASON AS ORIG_ENTRY_REASON,
       C.CUSTOMER_TYPE,
       K.AR_LVL,
       H.ORDER_NO
FROM PS_AR_STMT_CUSDT_H A,
     PS_CUST_ADDRESS B,
     PS_CUSTOMER C,
     PS_SET_CNTRL_REC E,
     PS_AR_STMT_CUST_H F,
     PS_ENTRY_TYPE_TBL D,
     PS_ENTRY_REASN_TBL G,
     OUTER PS_AR_ITEM_H H,
           OUTER PS_BI_TYPE K
WHERE A.ADDRESS_SEQ_NUM = B.ADDRESS_SEQ_NUM
  AND B.EFFDT =
    (SELECT MAX(B_ED.EFFDT)
     FROM PS_CUST_ADDRESS B_ED
     WHERE B.SETID = B_ED.SETID
       AND B.CUST_ID = B_ED.CUST_ID
       AND B.ADDRESS_SEQ_NUM = B_ED.ADDRESS_SEQ_NUM
       AND B_ED.EFFDT <= '06/19/2013')
  AND A.CRSPD_SETID = B.SETID
  AND A.CRSPD_CUST_ID = B.CUST_ID
  AND B.SETID = C.SETID
  AND B.CUST_ID = C.CUST_ID
  AND B.ADDRESS_SEQ_NUM = C.ADDRESS_SEQ_NUM
  AND G.ENTRY_TYPE = A.ENTRY_TYPE
  AND G.ENTRY_REASON = A.ENTRY_REASON
  AND G.SETID = E.SETID
  AND G.SETID = D.SETID
  AND G.ENTRY_TYPE = D.ENTRY_TYPE
  AND E.SETCNTRLVALUE = A.BUSINESS_UNIT
  AND E.RECNAME = 'ENTRY_TYPE_TBL'
  AND A.CRSPD_SETID = F.CRSPD_SETID
  AND A.CRSPD_CUST_ID = F.CRSPD_CUST_ID
  AND A.ST_ID_NUM = F.ST_ID_NUM
  AND A.BUSINESS_UNIT = H.BUSINESS_UNIT
  AND A.CUST_ID = H.CUST_ID
  AND A.ITEM = H.ITEM
  AND A.ITEM_LINE = H.ITEM_LINE
  AND substr(A.ENTRY_TYPE,1,3) = K.BILL_TYPE_ID
  AND K.SETID = 'SPN'
  AND K.EFFDT =
    (SELECT MAX(C_ED.EFFDT)
     FROM PS_BI_TYPE C_ED
     WHERE K.SETID = C_ED.SETID
       AND K.BILL_TYPE_ID = C_ED.BILL_TYPE_ID
       AND C_ED.EFFDT <= '06/19/2013')
  AND K.EFF_STATUS = 'A'
  AND A.CRSPD_CUST_ID = '000331'
  AND A.CRSPD_SETID = 'SPN'
  AND F.ST_DT = ''
  AND F.ST_ID_NUM = ''
GROUP BY A.CRSPD_SETID,
         A.CRSPD_CUST_ID,
         F.ST_ID_NUM,
         F.ST_DT,
         A.BUSINESS_UNIT ,
         H.ASOF_DT,
         H.DUE_DT,
         A.ITEM,
         H.CONTRACT_NUM,
         D.DESCR,
         G.DESCR,
         C.NAME1 ,
         B.ADDRESS1,
         B.ADDRESS2,
         B.ADDRESS3,
         B.ADDRESS4,
         B.CITY,
         B.STATE ,
         B.POSTAL,
         A.BAL_CURRENCY,
         A.CUST_ID,
         A.ENTRY_TYPE ,
         25,
         A.ENTRY_REASON,
         C.CUSTOMER_TYPE,
         K.AR_LVL,
         H.ORDER_NO
ORDER BY 2,
         3,
         4,
         25,
         8,
         11,
         24
4

3 回答 3

1

我是否正确 OUTER 只是 LEFT OUTER JOIN 的简写(可能是 Informix 风格的简写)?

是的,你是完全正确的。

引用Informix-4GL 参考手册

查询 1 - 使用简单联接

SELECT customer.customer_num, lname, order_num
    FROM customer, orders
    WHERE customer.customer_num = orders.order_num

查询 2 - 使用外部联接

SELECT customer.customer_num, lname, order_num
    FROM customer, OUTER orders
    WHERE customer.customer_num = orders.customer_num

在 Informix 中,当 OUTER 放在可以包含空值的表前面时,连接被指定为外部连接。

于 2013-06-20T14:27:14.467 回答
1

有关 Informix 外部语法的信息: http://pic.dhe.ibm.com/infocenter/idshelp/v117/index.jsp?topic= %2Fcom.ibm.sqls.doc%2Fsqls.htm

IBM 的时髦文档不允许直接链接,因此请在其中搜索 OUTER。

这是针对 Informix 11.7 的,不确定您使用的是什么版本。

本质上,外部表将是 where 子句中 ANY 连接条件中的从属表,并且实际上是左外连接。另请注意,在 from 子句中指定表的顺序对于 Informix 语法很重要。

于 2013-06-21T03:12:16.503 回答
1

Informix 样式的 OUTER 联接不仅仅是 LEFT OUTER JOIN 的捷径,而是将其视为这样的适度近似。有许多细节为什么它不是那么简单。

Informix OUTER Joins有一个在线解释,其中一些比您示例中的查询复杂得多。

将 UNION 查询的前半部分转换为更现代的表示法,您将得到:

SELECT A.CRSPD_SETID,
       A.CRSPD_CUST_ID,
       F.ST_ID_NUM AS STMT_NBR,
       F.ST_DT,
       A.BUSINESS_UNIT,
       H.ASOF_DT,
       H.DUE_DT,
       A.ITEM,
       H.CONTRACT_NUM,
       D.DESCR AS ENTRY_TYPE_DESCR,
       G.DESCR AS ENTRY_REASON_DESCR,
       SUM(A.BAL_AMT) AS ORIG_BAL_AMT,
       SUM(H.BAL_AMT),
       C.NAME1,
       B.ADDRESS1,
       B.ADDRESS2,
       B.ADDRESS3,
       B.ADDRESS4,
       B.CITY,
       B.STATE,
       B.POSTAL,
       A.BAL_CURRENCY,
       A.CUST_ID,
       A.ENTRY_TYPE AS ORIG_ENTRY_TYPE,
       CASE
           WHEN A.ENTRY_TYPE = 'PY'
                OR A.ENTRY_TYPE = 'BGB' THEN 'AA' || substr(A.ENTRY_TYPE,1,3)
           ELSE substr(A.ENTRY_TYPE,1,3)
       END,
       A.ENTRY_REASON AS ORIG_ENTRY_REASON,
       C.CUSTOMER_TYPE,
       K.AR_LVL,
       H.ORDER_NO
  FROM PS_STMT_CUST_DTL A
  JOIN PS_CUST_ADDRESS B
    ON A.ADDRESS_SEQ_NUM = B.ADDRESS_SEQ_NUM AND
       A.CRSPD_SETID = B.SETID AND
       A.CRSPD_CUST_ID = B.CUST_ID
  JOIN PS_CUSTOMER C
    ON B.SETID = C.SETID AND
       B.CUST_ID = C.CUST_ID AND
       B.ADDRESS_SEQ_NUM = C.ADDRESS_SEQ_NUM
  JOIN PS_SET_CNTRL_REC E
    ON E.SETCNTRLVALUE = A.BUSINESS_UNIT AND
       E.RECNAME = 'ENTRY_TYPE_TBL'
  JOIN PS_STMT_CUST F
    ON A.CRSPD_SETID = F.CRSPD_SETID AND
       A.CRSPD_CUST_ID = F.CRSPD_CUST_ID AND
       A.ST_ID_NUM = F.ST_ID_NUM
  JOIN PS_ENTRY_REASN_TBL G
    ON G.ENTRY_TYPE = A.ENTRY_TYPE AND
       G.ENTRY_REASON = A.ENTRY_REASON AND
       G.SETID = E.SETID AND
  JOIN PS_ENTRY_TYPE_TBL D
    ON G.SETID = D.SETID AND
       G.ENTRY_TYPE = D.ENTRY_TYPE
  LEFT OUTER JOIN PS_ITEM H
    ON A.BUSINESS_UNIT = H.BUSINESS_UNIT AND
       A.CUST_ID = H.CUST_ID AND
       A.ITEM = H.ITEM AND
       A.ITEM_LINE = H.ITEM_LINE
  LEFT OUTER JOIN PS_BI_TYPE K
    ON SUBSTR(A.ENTRY_TYPE,1,3) = K.BILL_TYPE_ID
 WHERE B.EFFDT =
       (SELECT MAX(B_ED.EFFDT)
          FROM PS_CUST_ADDRESS B_ED
         WHERE B.SETID = B_ED.SETID
           AND B.CUST_ID = B_ED.CUST_ID
           AND B.ADDRESS_SEQ_NUM = B_ED.ADDRESS_SEQ_NUM
           AND B_ED.EFFDT <= '06/19/2013')
   AND K.SETID = 'SPN'
   AND K.EFFDT =
       (SELECT MAX(C_ED.EFFDT)
          FROM PS_BI_TYPE C_ED
         WHERE K.SETID = C_ED.SETID
           AND K.BILL_TYPE_ID = C_ED.BILL_TYPE_ID
           AND C_ED.EFFDT <= '06/19/2013')
   AND K.EFF_STATUS = 'A'
   AND A.CRSPD_CUST_ID = '000331'
   AND A.CRSPD_SETID = 'SPN'
   AND F.ST_DT = ''
   AND F.ST_ID_NUM = ''
 GROUP BY A.CRSPD_SETID,
          A.CRSPD_CUST_ID,
          F.ST_ID_NUM,
          F.ST_DT,
          A.BUSINESS_UNIT ,
          H.ASOF_DT,
          H.DUE_DT,
          A.ITEM,
          H.CONTRACT_NUM,
          D.DESCR,
          G.DESCR,
          C.NAME1 ,
          B.ADDRESS1,
          B.ADDRESS2,
          B.ADDRESS3,
          B.ADDRESS4,
          B.CITY,
          B.STATE,
          B.POSTAL,
          A.BAL_CURRENCY,
          A.CUST_ID,
          A.ENTRY_TYPE,
          25,
          A.ENTRY_REASON,
          C.CUSTOMER_TYPE,
          K.AR_LVL,
          H.ORDER_NO

由于表的数量和多列连接条件,这相当复杂。然而,外连接结构是直截了当的——两个外连接都直接与主表 PS_STMT_CUST_DTL 相关,它被赋予别名 A。

我相当确定可以简化 SQL。例如,在编写时,Informix 可能不支持“FROM 子句中的子查询”。但是这两个 SUM 值可能会被放入一个子查询中,这将简化 GROUP BY 子句(从主查询中删除它)。

于 2013-06-21T14:43:59.693 回答