СУММА по столбцу из подзапроса в ORACLE

#sql #oracle #subquery

#sql #Oracle #подзапрос

Вопрос:

Я пытаюсь получить общее количество транзакций из таблицы между заданной датой в базе данных oracle.Я написал подзапрос для группировки уникальных транзакций, и когда я пытаюсь суммировать столбцы в подзапросе, я получаю сообщение об ошибке ORA-00904: ColumnName: недопустимый идентификатор. Я новичок в oracle, но это же работало для меня в sql server.

Вот мой запрос.

 select sum(Tots),sum(CRIR),sum(RT),sum(Succes) from( 

select  ds.LOAN_ID,ds.CUST_ID,TO_CHAR(ds.SENT_DT_TIME, 'YYYY-MM-DD') "Dates", count(*) "Tots", 
  SUM(DECODE (ds.STATUS, 'CR', 1,'IR',1,0)) "CRIR",
  SUM(DECODE (ds.STATUS, 'R', 1,'T',1,0)) "RT",
  SUM(DECODE (ds.STATUS, 'S', 1, 0)) "Succes"
  FROM DATA_STRING ds
  WHERE TRUNC(ds.SENT_DT_TIME) BETWEEN to_date('2016-10-04','yyyy-mm-dd') and to_date('2016-10-07','yyyy-mm-dd')
  Group by ds.LOAN_ID,ds.CUST_ID,TO_CHAR(ds.SENT_DT_TIME, 'YYYY-MM-DD')
); 
  

Комментарии:

1. Каково полное сообщение об ошибке? Это должно указать вам на строку и позицию идентификатора-нарушителя, это помогает? (Поделитесь этой информацией здесь, если вам нужна дополнительная помощь.)

Ответ №1:

Ваш запрос был бы намного проще записать как:

 select count(*),
       sum(case when status in ('CR', 'IR') then 1 else 0 end) as CRIR, 
       sum(case when status in ('R', 'T') then 1 else 0 end) as RT, 
       sum(case when status in ('S') then 1 else 0 end) as Succes
from data_string ds
where ds.sent_dt_time >= date '2016-10-04' and
      ds.sent_dt_time < date '2016-10-08';
  

Примечания:

  • Для того, что вы хотите сделать, не требуется два уровня агрегирования.
  • Используйте case вместо decode() , потому case что это стандартный SQL. Также проще включить такую логику, как in .
  • Oracle поддерживает date ключевое слово, за которым может следовать стандартная дата.
  • Почти точно такой же запрос работает в SQL Server (за вычетом date ключевого слова).

Комментарии:

1. Я хочу выполнить группировку, чтобы сгруппировать все уникальные транзакции за день

2. @Raju . , , Можно ответить только на вопрос, который вы задаете. Двойная агрегация не требуется. Если у вас есть другой вопрос, задайте его как другой вопрос. Если вы измените это, это может сделать недействительным этот ответ и, следовательно, привлечь отрицательные голоса.

3. почему это работает на SQL server, а не на Oracle ? !! .. Какие-либо ограничения в Oracle для двухуровневых агрегаций?

4. @Raju . , , я не говорил, что это не будет работать с двумя уровнями агрегации, просто эта версия проще и более переносима.

5. Если это так, то почему он выдавал ошибку для моего запроса. Я сделал что-то не так?

Ответ №2:

Только для вашей ошибки ORA-00904: ColumnName : invalid identifier

Если вы используете псевдонимы в кавычках для столбцов «Tots», «CRIR», «RT», «Succes» в подзапросе, то вам нужно использовать те же псевдонимы в кавычках в основном запросе.

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

Это будет работа:

 select sum("Tots"),sum("CRIR"),sum("RT"),sum("Succes") from( 

select  ds.LOAN_ID,ds.CUST_ID,TO_CHAR(ds.SENT_DT_TIME, 'YYYY-MM-DD') "Dates", count(*) "Tots", 
  SUM(DECODE (ds.STATUS, 'CR', 1,'IR',1,0)) "CRIR",
  SUM(DECODE (ds.STATUS, 'R', 1,'T',1,0)) "RT",
  SUM(DECODE (ds.STATUS, 'S', 1, 0)) "Succes"
  FROM DATA_STRING ds
  WHERE TRUNC(ds.SENT_DT_TIME) BETWEEN to_date('2016-10-04','yyyy-mm-dd') and to_date('2016-10-07','yyyy-mm-dd')
  Group by ds.LOAN_ID,ds.CUST_ID,TO_CHAR(ds.SENT_DT_TIME, 'YYYY-MM-DD')
);