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