排除非空和小于条件

Exclude not null and less than condition

我需要将数据整理成 2 个报告,用于 oracle 报告。以下是我整理所有内容的查询。现在我需要排除其他报告中显示的具有以下条件

的所有数据

一般来说,我想排除 client_no 在这种情况下没有价值的

WHERE ((CHQ_NO IS NOT NULL AND **CHQ_AMT>50000**)
or (CATEGORY='3' AND **CHQ_AMT>10000**))

1.第一份报告

WHERE ((CHQ_NO IS NOT NULL AND CHQ_AMT>50000) or (CATEGORY='3' AND CHQ_AMT>10000))

对于第二份报告,我使用了以下条件,它必须从第一份报告中排除条件。

第二次报告
WHERE ((CHQ_NO IS NOT NULL AND CHQ_AMT<50000) or (CATEGORY='3' AND CHQ_AMT<10000))

以下是我的代码,需要添加条件以排除报告 1

SELECT CLIENT_NO,
       sum(decode(category,'3',decode(nvl(cancel_flag,'N'),'N',1,-2) ,0)) CASH,
       sum(decode(chq_no, null,0, decode(nvl(cancel_flag,'N'),'N',1,-2))) CHQ,
       0 YTD_PURCHASE,
       0 YTD_SALES,
       0  CURRENT_CRLIMIT,
       0 CR_LIMIT 
FROM BOS_M_LEDGER_REC 
WHERE ((CHQ_NO IS NOT NULL AND CHQ_AMT<50000) or (CATEGORY='3' AND CHQ_AMT<10000)) 
and CLIENT_NO>=:P_CLIENT_NO_FROM 
AND CLIENT_NO <=:P_CLIENT_NO_TO 
AND TRAN_DATE>=:P_FROM_DATE 
AND TRAN_DATE<=:P_TO_DATE 
GROUP BY CLIENT_NO

请注意,您当前的代码从两个报告中排除了恰好 50,000 或 10,000 的支票金额,因为它们都不包含与这些值完全匹配的值 - 一个报告选择上面的值,另一个选择下面的值。我不知道这是故意的还是逻辑上的疏忽。

WITH common_report_subquery AS
(
    SELECT 
        CLIENT_NO

        ,DECODE(
                category
                ,'3', DECODE(
                            NVL(cancel_flag, 'N')
                            ,'N', 1
                            ,-2
                            ) 
                ,0
            ) AS CASH

        ,DECODE(
                chq_no
                ,NULL, 0
                ,DECODE(
                        NVL(cancel_flag, 'N')
                        ,'N', 1
                        ,-2
                        )
            ) AS CHQ


        ,IIF(
                ((CHQ_NO IS NOT NULL AND CHQ_AMT>50000) or (CATEGORY='3' AND CHQ_AMT>10000))
                ,1
                ,0
            ) AS MEETS_FIRST_REPORT_CRITERIA

        ,IIF(
                ((CHQ_NO IS NOT NULL AND CHQ_AMT<50000) or (CATEGORY='3' AND CHQ_AMT<10000))
                ,1
                ,0
            ) AS MEETS_SECOND_REPORT_CRITERIA


    FROM 
        BOS_M_LEDGER_REC 

    WHERE 
        ( CLIENT_NO BETWEEN :P_CLIENT_NO_FROM AND :P_CLIENT_NO_TO )
        AND 
        ( TRAN_DATE BETWEEN :P_FROM_DATE AND :P_TO_DATE )
)

,first_report AS
(
    SELECT
        CLIENT_NO
        ,SUM(CASH) AS CASH
        ,SUM(CHQ) AS CHQ

        ,0 AS YTD_PURCHASE
        ,0 AS YTD_SALES
        ,0 AS CURRENT_CRLIMIT
        ,0 AS CR_LIMIT

    FROM
        common_report_subquery

    WHERE 
        (MEETS_FIRST_REPORT_CRITERIA = 1) 

    GROUP BY 
        CLIENT_NO

)

,second_report_subquery AS
(
    SELECT
        *
        ,MAX(MEETS_FIRST_REPORT_CRITERIA) OVER (PARTITION BY CLIENT_NO ORDER BY NULL) AS CLIENT_APPEARS_ON_FIRST_REPORT

    FROM
        common_report_subquery

)

,second_report AS
(
    SELECT
        CLIENT_NO
        ,SUM(CASH) AS CASH
        ,SUM(CHQ) AS CHQ

        ,0 AS YTD_PURCHASE
        ,0 AS YTD_SALES
        ,0 AS CURRENT_CRLIMIT
        ,0 AS CR_LIMIT

    FROM
        second_report_subquery

    WHERE 
        (MEETS_SECOND_REPORT_CRITERIA = 1)
        AND
        --excludes consideration of any rows for clients that met the criteria for inclusion on the first report
        (CLIENT_APPEARS_ON_FIRST_REPORT = 0) 

    GROUP BY 
        CLIENT_NO
)

--uncomment the relevant line below for each report
--SELECT * FROM first_report
--SELECT * FROM second_report

我已添加逻辑以删除报告 1 中由别名 B 表示的子查询中的那些 client_no。在 client_no 上的完整外部联接中使用 B 中的 client_no 列表与您的原始 table(报告 2 别名 A)。如果不匹配,这将在 A.client_no 和 B.client_no 列中创建 NULL。

然后添加了一个 WHERE B.CLIENT_NO IS NULL,这意味着您将只有 client_noA 而不是 B[仅供参考,如果 B.client_no 不是NULL,这意味着与 A.client_no 匹配,而您不希望报告 3] 中出现 client_no。

我没有在查询的其他地方进行更改。

SELECT A.CLIENT_NO,
    sum(decode(category,'3',decode(nvl(cancel_flag,'N'),'N',1,-2) ,0)) CASH,
    sum(decode(chq_no, null,0, decode(nvl(cancel_flag,'N'),'N',1,-2))) CHQ,
    0 YTD_PURCHASE,
    0 YTD_SALES,
    0  CURRENT_CRLIMIT,
    0 CR_LIMIT 
FROM BOS_M_LEDGER_REC A
FULL OUTER JOIN
(SELECT CLIENT_NO FROM BOS_M_LEDGER_REC WHERE ((CHQ_NO IS NOT NULL AND CHQ_AMT>=50000) or (CATEGORY='3' AND CHQ_AMT>=10000)) GROUP BY CLIENT_NO) B
ON A.CLIENT_NO = B.CLIENT_NO
WHERE B.CLIENT_NO IS NULL
AND ((CHQ_NO IS NOT NULL AND CHQ_AMT<50000) or (CATEGORY='3' AND CHQ_AMT<10000)) 
AND A.CLIENT_NO>=:P_CLIENT_NO_FROM 
AND A.CLIENT_NO <=:P_CLIENT_NO_TO 
AND TRAN_DATE>=:P_FROM_DATE 
AND TRAN_DATE<=:P_TO_DATE 
GROUP BY A.CLIENT_NO;