Sql 如何在同一查询中减去两个选定列?

Sql 如何在同一查询中减去两个选定列?,sql,oracle,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 (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';

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

除了在
order by
子句中,您不能在定义的查询级别中引用列别名。这是因为查询的处理方式和结果集的构造,但也避免了歧义。其中提到:

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

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

select  SubQueryAlias.*
,       processed - rejected as approved
from    (
        select  (
                select count(*) 
                from   tbl_account
                ) as processed,            
                (
                select  count(*) 
                from    tbl_rejected_account
                ) as rejected
        from    dual
        ) as SubQueryAlias
;
或者如果您确实与第三个表有关联:

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
你还没有说关系是什么,所以我假设了一个公共ID列。使用CTE而不是内联视图,其外观如下:

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
如果任一子查询表可能没有匹配的行,则可能需要外部联接和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, 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

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

您不能在同一查询级别中使用列别名;但是
tbl_control
与子查询中的两个表之间的关系是什么?是否应该存在某种相关性?这三个表之间存在内部关系。但我跳过了一半查询,因为我想澄清一下。@AlexPoole请查看编辑。是的,这是最后的选择,再次写入完整子查询。我想跳过写入查询,只使用别名。如果您跳过写入查询,数据库如何知道别名的含义?我的意思是,我计算了已处理的帐户,然后计算了被拒绝的帐户,第三,我希望两者都有所不同。但我不想再次计算处理过的和拒绝过的,然后两者都减去,而是想找到一种方法,如果我可以使用别名从另一个中减去一个。
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