在 ORACLE 中的子查询的列上求和

Posted

技术标签:

【中文标题】在 ORACLE 中的子查询的列上求和【英文标题】:SUM on a column from subquery in ORACLE 【发布时间】:2016-10-06 02:36:39 【问题描述】:

我试图在 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】:

您的查询可以更简单地写成:

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 关键字)。

【讨论】:

我想通过分组来分组一天中的所有唯一交易 @Raju 。 . .只能回答您提出的问题。不需要双重聚合。如果您有 另一个 问题,则将其作为 另一个 问题提出。如果你修改这个,它可能会使这个答案无效,从而吸引反对票。 为什么它在 SQL Server 上而不是在 Oracle 上工作?!!..Oracle 中对两级聚合有任何限制吗? @Raju 。 . .我并不是说它不适用于两个级别的聚合,只是这个版本更简单、更便携。 如果这就是为什么它为我的查询抛出错误的原因。我做错什么了吗?【参考方案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')
); 

【讨论】:

以上是关于在 ORACLE 中的子查询的列上求和的主要内容,如果未能解决你的问题,请参考以下文章

SQL 不能使用从 group by 中的子查询返回的列

选择语句中的子查询如何在 oracle 中工作

Oracle SQL 中的子查询

ORACLE LEFT JOIN 子查询 在SQL SERVER中可以使用如图中的子查询,ORACLE中怎么实现

如何在子查询中使用外部查询中的列从另一个表中获取结果?

FROM 中的子查询在 Oracle SQL 中不起作用