您的问题已经得到解答,但有些人的情况可能略有不同,他们需要根据列而不是固定日期获取最新的 EFFDT。对于这些情况,我只找到了一个不完美的选项和一个丑陋的解决方案......
不完美的选择:
SELECT ...
FROM MYTABLE N, CUST_OPT C
WHERE etc...
AND C.SETID (+) = N.SETID
AND C.CUST_ID (+) = N.CUST_ID
AND NVL(C.EFFDT,TO_DATE('01011900','DDMMYYYY')) = NVL((SELECT MAX(EFFDT)
FROM CUST_OPT SC
WHERE SC.SETID = C.SETID
AND SC.CUST_ID = C.CUST_ID
AND SC.EFFDT <= N.ISSUE_DT)
,TO_DATE('01011900','DDMMYYYY'))
这是一个不完美的选择,因为如果 CUST_OPT 表有未来日期,但没有当前 (<=N.ISSUE_DT) 日期,则外连接将不起作用并且不会返回任何行。一般而言,PeopleSoft 术语(是的,我在那里看到了您的 SETID+EFFDT!;-D)这不会经常发生,因为人们倾向于创建一个 01/01/1900 EFFDT 以使第一个值从“永远”开始有效,但因为并非总是如此;我们还有一个丑陋的解决方案:
我还找到了一个 UGLY 选项(但我实际上是推荐它,它解决了问题,所以我们称之为解决方案),就是这样:
SELECT n.field1, n.field2,
CASE WHEN NVL(c.EFFDT,n.ISSUE_DT-1)<=n.ISSUE_DT THEN c.field1 ELSE NULL END,
CASE WHEN NVL(c.EFFDT,n.ISSUE_DT-1)<=n.ISSUE_DT THEN c.field2 ELSE NULL END
FROM MYTABLE N, CUST_OPT C
WHERE etc...
AND C.SETID (+) = N.SETID
AND C.CUST_ID (+) = N.CUST_ID
AND NVL(C.EFFDT,TO_DATE('01011900','DDMMYYYY')) = NVL((SELECT MAX(EFFDT)
FROM CUST_OPT SC
WHERE SC.SETID = C.SETID
AND SC.CUST_ID = C.CUST_ID
AND SC.EFFDT <= N.ISSUE_DT)
,NVL( (SELECT MIN(EFFDT)
FROM CUST_OPT SC
WHERE SC.SETID = C.SETID
AND SC.CUST_ID = C.CUST_ID
AND SC.EFFDT >= N.ISSUE_DT)
,TO_DATE('01011900','DDMMYYYY')
)
)
此选项将返回必须忽略的未来行!因此,我们在 SELECT 语句中添加条件,如果它们不打算被检索,则将 IGNORE 返回值。就像我说的......这是一个丑陋的解决方案,但它是一个解决方案。
对于我丑陋的解决方案,如果稍后将在应用程序引擎或 PL/SQL 或其他任何东西中处理这些行;您可以,而不是为每列添加一个 CASE 语句,只需添加一个新列,它会告诉您您获取了“不正确”的数据,并根据此列忽略代码中稍后的字段,如下所示:
CASE WHEN NVL(c.EFFDT,n.ISSUE_DT-1)<=n.ISSUE_DT THEN 'N' ELSE 'Y' END AS IGNORE_CUST_OP_COLS