SQL聚合逻辑 - 不确定

时间:2015-11-07 08:36:13

标签: sql aggregation

我通过在视图中加入它们来实现两个表之间的多个单独逻辑。我需要在实现所有逻辑的情况下获得最少数量的视图。在实施过程中,我对以下问题感到震惊并需要您的专业知识。

我已经到达了视图的基本逻辑,因为它是大多数逻辑的基础,我会坚持下去;

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并获得上述值。

1 个答案:

答案 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');