在 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 中的子查询的列上求和的主要内容,如果未能解决你的问题,请参考以下文章