排除非空且小于条件

时间:2017-12-26 05:01:37

标签: sql oracle oraclereports

我需要将数据整理成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

2 个答案:

答案 0 :(得分:0)

请注意,您当前的代码会从两个报告中排除正好为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 :(得分:0)

我添加了逻辑,用于删除别名client_no所代表的子查询中报表1中的B。使用client_noB的{​​{1}}列表client_no与您的原始表格一起使用{报告2,其中包含别名A)。如果存在不匹配,这将在A.client_no和B.client_no列中创建NULL。

然后添加了WHERE B.CLIENT_NO IS NULL,这意味着您只有client_no A而不是B [FYI如果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;