我怎样才能在同一个查询中减去两个选定的列?

时间:2016-01-02 11:26:05

标签: sql oracle

select (select count(*) from tbl_account) as processed,
(select count(*) from tbl_rejected_account) as rejected,
processed -rejected as approved from tbl_control .

如何在不必编写两个子查询的情况下获得“已批准”计数,并在以后减去它们。

修改

我想要更改的原始查询:

 select 
ACTIVITY_DATE 
,SYSTEM_NAME 
,START_TIME 
,END_TIME 
,INSTANCE_NO as instance_number
,case status when '1' then 'Success'
when '2' then 'In process'
when '3' then 'Failed' end as status

,(select count(distinct account_number) from tbl_account_detail where   coretype=a.system_name and INSTANCE_NO=a.instance_no and a.activity_date=to_char(upload_date,'dd-MON-yy'))+

(select count(distinct account_number) from tbl_account_detail_exception where  system_name=a.system_name and INSTANCE_NO=a.instance_no and a.activity_date=to_char(upload_date,'dd-MON-yy'))
as AccountCount
,(select count(distinct account_number) from tbl_account_detail where  CREATOR='SYSTEM' and APPROVER='SYSTEM' and system_name=a.system_name and INSTANCE_NO=a.instance_no and a.activity_date=to_char(upload_date,'dd-MON-yy')) 
as AutoApprovedCount
    ,(select count(distinct account_number) from tbl_account_detail where  coretype=a.system_name and INSTANCE_NO=a.instance_no and a.activity_date=to_char(upload_date,'dd-MON-yy')) +

 (select count(distinct account_number) from tbl_account_detail_exception where  system_name=a.system_name and INSTANCE_NO=a.instance_no and 

a.activity_date=to_char(upload_date,'dd-MON-yy')) -

(select count(distinct account_number) from tbl_account_detail where a.activity_date=to_char(upload_date,'dd-MON-yy') and CREATOR='SYSTEM' and APPROVER='SYSTEM' and system_name=a.system_name and INSTANCE_NO=a.instance_no)
    as MaintenanceCount
    from tbl_control_file_status a where activity_type='MAIN' and activity_name='START';
显然,这不应该是正确的方式,请提供替代解决方案。

2 个答案:

答案 0 :(得分:2)

您可以使用子查询引入别名以在外部查询中使用:

a <-cbind(expand.grid(seq(1,5,1),seq(1,5,1)),
          strength = c(-11, 61, 230, 118, 156, 98, 169, 306, 6, -54,   
                       207, -32, 27, 128, 101, 19, -18, 32, 153, 14, 
                       63, 136, 165, 73, 35))
a <- a[order(a$strength, decreasing=T),]

V <- matrix(nrow=5,ncol=3)
for (i in 1:nrow(a)) {
    if( sum(is.na(V[,1])) == 0)
        break
    if( !(a[i,1] %in% V[,1]) & !(a[i,2] %in% V[,2])) {
        j <- a[i,1]
        V[j,1] <- a[i,1]
        V[j,2] <- a[i,2]
        V[j,3] <- a[i,3]
    }
}

在Alex Poole的回答中,使用公用表表达式(CTE)通常更具可读性。

答案 1 :(得分:1)

除了order by子句之外,您无法在定义的查询级别中引用列别名。这是因为处理查询的方式和构造的结果集,但也避免了歧义。这是in the documentatin

  

指定列表达式的别名。 Oracle数据库将在结果集的列标题中使用此别名。 AS关键字是可选的。别名在查询期间有效地重命名选择列表项。别名可以在order_by_clause中使用,但不能在查询中使用其他子句。

您可以为每个子查询或内联视图使用CTE:

select ta.processed, tra.rejected, ta.processed - tra.rejected as approved
from (
  select count(*) as processed from tbl_account
) ta
cross join (
  select count(*) as rejected from tbl_rejected_account
) tra

或者如果你真的与第三个表有关联:

select tc.id, ta.processed, tra.rejected, ta.processed - tra.rejected as approved
from tbl_control tc
join (
  select id, count(*) as processed from tbl_account group by id
) ta on ta.id = tc.id
join (
  select id, count(*) as rejected from tbl_rejected_account group by id
) tra on tra.id = tc.id

你还没有说出这种关系是什么,所以我假设了一个共同的ID列。使用CTE而不是内联视图,如下所示:

with ta as (
  select id, count(*) as processed from tbl_account group by id
), tra as (
  select id, count(*) as rejected from tbl_rejected_account group by id
)
select tc.id, ta.processed, tra.rejected, ta.processed - tra.rejected as approved
from tbl_control tc
join ta on ta.id = tc.id
join tra on tra.id = tc.id

如果子查询表中可能没有匹配的行,则可能需要外连接和nvl。

你真的不需要在这里使用子查询,内联视图或CTE;您可以加入表并在顶级查询中包含聚合 - 您需要复制计数而不是整个子查询:

with ta as (
  select id, count(*) as processed from tbl_account group by id
), tra as (
  select id, count(*) as rejected from tbl_rejected_account group by id
)
select tc.id, count(ta.id) as processed,
  count(tra.id) as rejected,
  count(ta.id) - count(tra.id) as approved
from tbl_control tc
join tbl_approved ta on ta.id = tc.id
join tbl_rejected tra on tra.id = tc.id
group by tc.id

当然,您可以根据需要添加更多联接和条件。