2013-03-21 76 views
2

我有一张表,我希望总是显示一个字段(帐户),然后子查询计数或带标准的总和。SQL子查询来自同一个表的所有数据

例子:

select ndhist_acct_nbr,  
    (select count(ndhist_acct_nbr) from dbo.nd_history where ndhist_type = '30' 
     and ndhist_rsn = '0' and ndhist_trcd = 'NF*' and ndhist_ref_type = '0' and ndhist_dt >= '03/01/2013') as NSF_TOTAL, 
    (select sum(ndhist_amt) from dbo.nd_history where ndhist_type = '30' 
     and ndhist_rsn = '98' and ndhist_trcd = 'TW0' and ndhist_ref_type = '11' and ndhist_dt >= '03/01/2013') as SIG_SPEND, 
    (select count(ndhist_acct_nbr) from dbo.nd_history where ndhist_type = '30' 
     and ndhist_rsn = '23' and ndhist_trcd = 'TW0' and ndhist_ref_type = '11' and ndhist_dt >= '03/01/2013') as PIN_TRANS, 
    (select count(ndhist_acct_nbr) from dbo.nd_history where ndhist_type = '30' 
     and ndhist_rsn = '21' and ndhist_trcd = 'SC*' and ndhist_ref_type = '0' and ndhist_dt >= '03/01/2013') as FOREIGN_AMT_FEE 
from dbo.nd_history 
group by ndhist_acct_nbr 

问题是结果 - 所有的帐户号码的出现,但计数/总和字段的所有重复数据。任何帮助都是极好的!

+2

欢迎来到Stack Overflow!请通过添加适当的标记(Oracle,SQL Server,MySQL等)来指定您要定位的RDBMS。可能会有利用不被普遍支持的语言或产品功能的答案。此外,通过为特定的RDBMS添加标签,您的问题可能会得到更适合回答的人的关注。 – Taryn 2013-03-21 12:04:45

回答

1

尝试:

select ndhist_acct_nbr,  
     count(case when ndhist_type = '30' and ndhist_rsn = '0' and ndhist_trcd = 'NF*' and ndhist_ref_type = '0' and ndhist_dt >= '03/01/2013' 
        then ndhist_acct_nbr end) as NSF_TOTAL, 
     sum(case when ndhist_type = '30' and ndhist_rsn = '98' and ndhist_trcd = 'TW0' and ndhist_ref_type = '11' and ndhist_dt >= '03/01/2013' 
       then ndhist_amt end) as SIG_SPEND, 
     count(case when ndhist_type = '30' and ndhist_rsn = '23' and ndhist_trcd = 'TW0' and ndhist_ref_type = '11' and ndhist_dt >= '03/01/2013' 
        then ndhist_acct_nbr end) as PIN_TRANS, 
     count(case when ndhist_type = '30' and ndhist_rsn = '21' and ndhist_trcd = 'SC*' and ndhist_ref_type = '0' and ndhist_dt >= '03/01/2013' 
        then ndhist_acct_nbr end) as FOREIGN_AMT_FEE 
from dbo.nd_history 
group by ndhist_acct_nbr 

您可以通过将整个查询的在线查询内,然后从中选择使用源自结果列 - 像这样:

select sq.*, 
     NSF_TOTAL*5 + SIG_SPEND*0.10 + PIN_TRANS*0.05 + FOREIGN_ATM_FEE as TOTAL_INCOME 
from 
(select ndhist_acct_nbr,  
     count(case when ndhist_type = '30' and ndhist_rsn = '0' and ndhist_trcd = 'NF*' and ndhist_ref_type = '0' and ndhist_dt >= '03/01/2013' 
        then ndhist_acct_nbr end) as NSF_TOTAL, 
     sum(case when ndhist_type = '30' and ndhist_rsn = '98' and ndhist_trcd = 'TW0' and ndhist_ref_type = '11' and ndhist_dt >= '03/01/2013' 
        then ndhist_amt end) as SIG_SPEND, 
     count(case when ndhist_type = '30' and ndhist_rsn = '23' and ndhist_trcd = 'TW0' and ndhist_ref_type = '11' and ndhist_dt >= '03/01/2013' 
        then ndhist_acct_nbr end) as PIN_TRANS, 
     count(case when ndhist_type = '30' and ndhist_rsn = '21' and ndhist_trcd = 'SC*' and ndhist_ref_type = '0' and ndhist_dt >= '03/01/2013' 
        then ndhist_acct_nbr end) as FOREIGN_AMT_FEE 
from dbo.nd_history 
group by ndhist_acct_nbr) sq 

可以这样做如果您正在使用支持CTE的RDBMS(如Oracle,PostgreSQL或SQLServer),那么通过CTE更优雅。

+0

这是完美的 - 如果我想添加一个最后一块:创建收入的列(NSF_TOTAL)* 5)+((SIG_SPEND)* 0.10%)+((PIN_TRANS)* $ 0.05)+((FOREIGN_ATM_FEE)* $ 1.00 ))作为TOTAL_INCOME – 2013-03-21 12:23:05

+0

@TomMurphy:我已经更新了我的回答,以说明如何完成此工作 - 目前,它正在使用SIG_SPEND的10%;如果您想要0.1%,那么将TOTAL_INCOME的SIG_SPEND组件更改为SIG_SPEND * 0.001。 – 2013-03-21 12:43:31

1

您的子查询是独立的 - 它们不以任何方式依赖ndhist_acct_nbr字段,因此结果始终相同。

此外,这种技术(对输出的每一行使用这种许多子查询)是一个坏主意。 您应该简化查询,而不是count distinct和子查询,使sum(case when ...子句。