2016-01-02 3 views
1
select (select count(*) from tbl_account) as processed, 
(select count(*) from tbl_rejected_account) as rejected, 
processed -rejected as approved from tbl_control . 

Как я могу получить этот «утвержденный» счет, не записывая два подзапроса и вычитая их позже.Как я могу вычесть два выделенных столбца в одном запросе?

EDIT:

оригинальный запрос, что я хочу изменить: -

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'; 

ясно, что это не то, что должно быть надлежащим образом, любезно предоставить альтернативное решение.

+0

Вы не можете использовать псевдонимы столбцов на одном уровне запроса; но какова связь между 'tbl_control' и двумя таблицами в подзапросах - должна ли быть некоторая корреляция? –

+0

существует внутренняя связь между этими тремя таблицами. Но я пропустил половину запроса, потому что я хотел сделать себя понятным. –

+0

@AlexPoole, см. Редактирование. –

ответ

0

Вы можете использовать подзапрос ввести псевдонимы для использования во внешнем запросе:

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 
; 

Это часто более удобное для чтения, чтобы использовать выражение общей таблицы (КТР), как в ответе Алекс Пула.

+0

Да, это было бы последним средством, чтобы снова написать полный подзапрос. Мне захотелось пропустить запись запроса и просто использовать псевдонимы. –

+0

Если вы пропустите запись запроса, как база данных может знать, что означает псевдоним? – Andomar

+0

что я имел в виду, я подсчитал обработанную учетную запись, затем подсчитал отклоненную, третью, я хочу разницу в обоих. Но я не хочу снова считать обработанные и отклоненные, а затем вычесть их, а я хотел найти способ, если я мог бы использовать псевдонимы для вычитания одного из другого. –

0

Вы не можете ссылаться на псевдоним столбца на том же уровне запроса, который определен, за исключением предложения order by. Это связано с тем, как обрабатывается запрос и создается результирующий набор, но также избегает двусмысленности. Это упоминается in the documentatin:

Укажите псевдоним для выражения столбца. Oracle Database будет использовать этот псевдоним в заголовке столбца набора результатов. Ключевое слово AS необязательно. Псевдоним эффективно переименовывает элемент списка выбора в течение всего времени запроса. Псевдоним может использоваться в order_by_clause, но не в других предложениях запроса.

Вы можете использовать СТЕ для каждого подзапроса или инлайн просмотров:

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 

Вы не сказали, что такое отношения, поэтому я принял общий столбец идентификаторов. Использование КТР, а не встроенные представления, которые будут выглядеть следующим образом:

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 

Вы можете добавить больше соединений и условие по мере необходимости, конечно.