4

此 SQL 查询似乎命中 ORA 00920。

select username, count(*)
from host
where created_dt 
between to_date('2012-may-23 00:00:00', 'yyyy-mon-dd hh24:mi:ss') 
and to_date('2012-may-23 23:59:59', 'yyyy-mon-dd hh24:mi:ss')
GROUP BY CASE
             WHEN REGEXP_LIKE(username, '^\d+$') THEN 'GRP_OTHERS'
                                                 ELSE username
         END;
4

2 回答 2

3

我没有可使用的 Oracle DB,但我想这可能是因为您选择username但不按它分组。您应该能够通过使用子查询来解决这个问题:

select username, count(*)
from (select CASE
             WHEN REGEXP_LIKE(username, '^\d+$') THEN 'GRP_OTHERS'
                                                 ELSE username
         END as username
      from host
      where created_dt 
      between to_date('2012-may-23 00:00:00', 'yyyy-mon-dd hh24:mi:ss') 
          and to_date('2012-may-23 23:59:59', 'yyyy-mon-dd hh24:mi:ss')
     )
GROUP BY username;
于 2012-05-26T14:25:51.923 回答
1

我不太相信你发布的内容......

您的查询应该抛出ORA-00979: Not a GROUP BY expression. 这是因为未包含在分析函数中的列,即username未反映在您的group by.

ORA-00920 表示您缺少以下内容之一:=, <>, not in, in, !=, is not null, is null, not like, like等等。您确定您发布了正确的查询吗?

在 11.2 中,创建类似于您的表格的内容,如下所示:

create table host
(  username varchar2(100)
 , created_dt date );

 insert into host
 select level, sysdate - level
   from dual
connect by level <= 10
        ;

 insert into host
 select chr(ascii(level) + 32), sysdate - level
   from dual
connect by level <= 10
        ;
 commit ;

然后运行查询在 ORA-00979 中发布结果。将其更改为以下工作很好。:

select case when regexp_like(username, '^\d+$') then 'GRP_OTHERS'
            else username end as username
     , count(*)
  from host
 where created_dt between
       to_date('2012-may-23 00:00:00', 'yyyy-mon-dd hh24:mi:ss') and
       to_date('2012-may-23 23:59:59', 'yyyy-mon-dd hh24:mi:ss')
 group by case when regexp_like(username, '^\d+$') then 'GRP_OTHERS'
               else username end
       ;

这也可以重写为:

select distinct username
     , count(*) over ( partition by case when regexp_like(username, '^\d+$') 
                                               then 'GRP_OTHERS'
                                          else username end )
  from host
 where created_dt between
       to_date('2012-may-23 00:00:00', 'yyyy-mon-dd hh24:mi:ss') and
       to_date('2012-may-23 23:59:59', 'yyyy-mon-dd hh24:mi:ss')

我认为第二个查询更像你想要的。它返回实际的用户名,但将所有只是数字的用户名组合在一起。如果您想查看,只需替换案例返回的用户名列GRP_OTHERS

最好不要在 Oracle 中使用mon格式模型,因为它不一定是跨语言一致的。改为使用mm


当您使用 9i 时,您可以使用 translate。将正则表达式替换为:

trim(translate(username,'0123456789',' ')) is null

这将数字替换为空,然后检查是否有任何剩余...

于 2012-05-26T15:01:39.037 回答