2015-11-07 61 views
0

我通过在视图连接它们执行2个表之间的多个单独的逻辑。我需要实现所有逻辑的最小数量的视图。我在实施时遇到以下问题,并需要您的专业知识。SQL聚集逻辑 - 不知道

我已经到了该视图的基础逻辑,因为它作为基地的大部分逻辑的,我要坚持下去;

SELECT Acct_no, max(txn_date),...... 
FROM ACCT_CRD ac 
INNER JOIN TRNSCTN txn ON (ac.crd_no = txn.crd_no) 
GROUP BY ACCT_NO, TO_CHAR(TXN_DATE,'YYYYMM'); 

TABLE_NAME:ACCT_CRD(此表有帐户,并与UPI的信用卡号码的信用卡号码和一个帐号可以有多个card_numbers)

数据:

Acct_no | Crd_no | biz_date | Status 
--------+--------+------------+-------- 
acct1 | crd11 | 2015-10-01 | A 
--------+--------+------------+-------- 
acct1 | crd12 | 2015-10-02 | A 
--------+--------+------------+-------- 
acct1 | crd13 | 2015-10-03 | A 

TABLE_NAME :TRNSCTN(该表已经通过交易的信用卡进行;数据并不反映任何实际意义)请注意,此表有用5年时间日期,样品,我已经花了仅仅1个月;

数据:

Crd_no | Txn_date | Txn_code | crd_limit | crd_commit 
--------+-------------+----------+-------------+------------ 
crd11 | 2015-10-02 | 10  | 10000  | 9000 
--------+-------------+----------+-------------+------------ 
crd11 | 2015-10-02 | 10  | 10000  | 14000 
--------+-------------+----------+-------------+------------ 
crd11 | 2015-10-02 | 20  | 10000  | 16000 
--------+-------------+----------+-------------+------------ 
crd11 | 2015-10-03 | 20  | 10000  | 12000 
--------+-------------+----------+-------------+------------ 
crd11 | 2015-10-05 | 20  | 10000  | 15000 
--------+-------------+----------+-------------+------------ 
crd12 | 2015-10-03 | 10  | 20000  | 5000 
--------+-------------+----------+-------------+------------ 
crd12 | 2015-10-03 | 20  | 20000  | 22000 
--------+-------------+----------+-------------+------------ 
crd12 | 2015-10-04 | 30  | 20000  | 25000 
--------+-------------+----------+-------------+------------ 
crd12 | 2015-10-04 | 30  | 20000  | 5000 
--------+-------------+----------+-------------+------------ 
crd13 | 2015-10-04 | 30  | 25000  | 10000 

在这里,TRNSCTN表,对每一天每一个卡,如果CRD_COMMIT> CRD_LIMIT,然后取数为1,即使有更多的记录有相同CARD_NO与crd_commit txn_date> = crd_limit或crd_commit < crd_limit;

订单是不是在某一天的交易很重要;

SELECT crd_no, txn_date, 
MAX(case when crd_commit > crd_limit then 1 else 0 end) day_overlimit_cnt 
FROM TRNSCTN group by crd_no, txn_date; 

从本质上讲,在表上面的数据转换为

Crd_no | txn_date | day_overlimit_cnt 
-------+-------------+------------------- 
crd11 | 2015-10-02 | 1 
-------+-------------+------------------- 
crd11 | 2015-10-03 | 1 
-------+-------------+------------------- 
crd11 | 2015-10-05 | 1 
-------+-------------+------------------- 
crd12 | 2015-10-03 | 1 
-------+-------------+------------------- 
crd12 | 2015-10-04 | 1 
-------+-------------+------------------- 
crd13 | 2015-10-04 | 0 

然后,我需要找到一个特定的月份,它已经多少次超过day_overlimit_cnt每张卡;

SELECT crd_no, to_char(txn_date,'yyymm') as txn_mnth, 
SUM(day_overlimit_cnt) sum_month_ovrlmt from (select crd_no, txn_date,  
MAX(case when crd_commit > crd_limit then 1 else 0 end) day_overlimit_cnt 
FROM TRNSCTN group by crd_no, txn_date) dt_check 
GROUP BY crd_no, to_char(txn_date,'yyymm'); 

从上述查询的数据将是

Crd_no | txn_mnth | sum_month_ovrlmt 
-------+----------+----------------- 
crd11 | 201510 | 3 
-------+----------+----------------- 
crd12 | 201510 | 2 
-------+----------+----------------- 
crd13 | 201510 | 0 

然后终于通过接合上述一至ACCT_CRD找到帐户一级最大(sum_month_ovrlmt);

SELECT acct_no, MAX(sum_month_ovrlmt) acct_mnth_ovrlmt 
FROM ACCT_CRD ac 
JOIN (SELECT crd_no, to_char(txn_date,'yyymm') as txn_mnth,  
SUM(day_overlimit_cnt) sum_month_ovrlmt FROM (SELECT crd_no, txn_date, MAX(case when crd_commit > crd_limit then 1 else 0 end) day_overlimit_cnt FROM TRNSCTN group by crd_no, txn_date) dt_check GROUP BY crd_no, to_char(txn_date,'yyymm')) dt_dt_check dt on (ac.cr_no = dt.crd_no) GROUP BY acct_no; 

最终输出:

Acct_no | acct_mnth_ovrlmt 
--------+----------------- 
acct1 | 3 

如何嵌入上述逻辑成以下基本查询;这就是如何在不影响select部分中的其他列数据的情况下派生acct_mnth_ovrlmt。

SELECT Acct_no, max(txn_date),...... 
FROM ACCT_CRD ac 
INNER JOIN TRNSCTN txn ON (ac.crd_no = txn.crd_no) 
GROUP BY ACCT_NO, TO_CHAR(TXN_DATE,'YYYYMM'); 

在此先感谢您的时间。作为最后的手段,我会尝试嵌入上面的派生代码,直到将卡片聚合到基本查询中并将尝试它。

问候Gordon Linoff, 感谢您的留言。我需要您在card_number级别提到的不同条件计数。而作为ACCOUNT_NUMBER可以有超过1个CARD_NUMBER,我需要找出在account_level最大(overlimit_cnt); 即,说如果不同条件计数为

crd11 | 3 
crd12 | 2 
crd13 | 0 

因为所有这些card_numbers属于acct1,需要获得上述card_numbers的最大值(overlimit_cnt);即,

acct | 3 

我想我需要再有另外加入到同一个表组由不同的列

SELECT Acct_no, max(txn_date),......,MAX(day_overlimit_cnt) 
FROM ACCT_CRD ac 
INNER JOIN TRNSCTN txn ON (ac.crd_no = txn.crd_no) 
INNER JOIN (SELECT CRD_NO, TO_CHAR(TXN_DATE,'YYYYMM') AS TXN_DATE_Y, 
COUNT(DISTINCT (CASE WHEN crd_commit > crd_limit then TXN_DATE end)) day_overlimit_cnt from TRNSCTN GROUP BY CRD_NO, TO_CHAR(TXN_DATE,'YYYYMM')) TRNSCTN_OVRLMT ON (TRNSCTN.CRD_NO=TRNSCTN_OVRLMT.CRD_NO AND TO_CHAR(TRNSCTN.TXN_DATE,'YYYYMMDD')=TRNSCTN_OVRLMT.TXN_DATE_Y) GROUP BY ACCT_NO, TO_CHAR(TXN_DATE,'YYYYMM'); 

我能避免新加入TRNSCTN_OVRLMT并得出上述数值。

回答

0

你的逻辑是有点难以遵循,但我觉得你只是想有条件数不同:

SELECT Acct_no, max(txn_date), 
     COUNT(DISTINCT (CASE WHEN crd_commit > crd_limit THEN txn_date END)) as DaysOverLimit 
FROM ACCT_CRD ac INNER JOIN 
    TRNSCTN txn 
    ON ac.crd_no = txn.crd_no 
GROUP BY ACCT_NO, TO_CHAR(TXN_DATE,'YYYYMM'); 
+0

谢谢戈登·利诺夫;我已经在我的帖子中用上面的编辑代码进行了额外的连接处理;感谢您的逻辑DISTINCT(CASE当crd_commit> crd_limit,然后TXN_DATE结束)良好的学习 – chill3chee