我通过在视图中加入它们来实现两个表之间的多个单独逻辑。我需要在实现所有逻辑的情况下获得最少数量的视图。在实施过程中,我对以下问题感到震惊并需要您的专业知识。
我已经到达了视图的基本逻辑,因为它是大多数逻辑的基础,我会坚持下去;
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和txn_date与crd_commit> = 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来找到帐户级别的max(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
如何将上述逻辑嵌入到以下基本查询中;这是如何派生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');
提前感谢您的时间。作为最后的手段,我将尝试嵌入上面的派生代码,直到将卡聚合到基本查询中并尝试它。
问候戈登林诺夫, 谢谢你的文章。我需要你在card_number级别提到的不同的条件计数。由于account_number可以有多个card_number,我需要在account_level找出max(overlimit_cnt); 即,说明不同的条件计数是否为
crd11 | 3
crd12 | 2
crd13 | 0
由于所有这些card_number都属于acct1,需要获取上述card_numbers的max(overlimit_cnt);即,
acct | 3
我想我需要再次在同一个表中使用group by作为
的不同列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 :(得分: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');