查询返回 ORA-00936: 缺少表达式

Posted

技术标签:

【中文标题】查询返回 ORA-00936: 缺少表达式【英文标题】:Query returns ORA-00936: missing expression 【发布时间】:2017-05-26 08:03:27 【问题描述】:

我正在运行以下查询,试图找出第一个插入行的重复实例是否存在:-

    SELECT COUNT(*)
    FROM rlx_service_info
    WHERE row(personalaccountid,serviceid,serviceline,
              userserviceid,servicerf) IN (SELECT personalaccountid,
                                                  serviceid,
                                                  serviceline,
                                                  userserviceid,
                                                  servicerf
                                             FROM rlx_service_info
                                            WHERE masteraccountid = 'x'
                                              AND status          = 30
                                              AND rownum          =1
                                            ORDER BY startdate );

【问题讨论】:

在 Oracle 中使用 row() 无效。 @NicholasKrasnov 难怪我找不到文档... 【参考方案1】:

要修复语法,您必须删除 roworder by 子句。 此外,如果子查询仅给出一行 (rownum = 1),则不需要 IN

SELECT COUNT(*)
  FROM rlx_service_info
 WHERE (personalaccountid,
        serviceid,
        serviceline,
        userserviceid,
        servicerf) = (  SELECT personalaccountid,
                                serviceid,
                                serviceline,
                                userserviceid,
                                servicerf
                           FROM rlx_service_info
                          WHERE     masteraccountid = 'x'
                                AND status = 30
                                AND ROWNUM = 1)

例如:

SQL> select 1
  2  from dual
  3  where (1, 2) in ( select 1, 2 from dual);

         1
----------
         1

SQL> select 1
  2  from dual
  3  where row(1, 2) in ( select 1, 2 from dual);
where row(1, 2) in ( select 1, 2 from dual)
               *
ERROR at line 3:
ORA-00936: missing expression

但是,如果您需要子查询只返回具有最小startDate 的一行,请考虑将order byrownum 条件结合使用不是一种方法;你会找到很多关于如何做到这一点的好答案。

例如:

SQL> select *
  2  from (
  3          select 1 x from dual union all
  4          select 2 x from dual
  5       )
  6  where rownum = 1
  7  order by x;

         X
----------
         1

SQL> select *
  2  from (
  3          select 2 x from dual union all
  4          select 1 x from dual
  5       )
  6  where rownum = 1
  7  order by x;

         X
----------
         2

【讨论】:

它说 ORA-00920: 在最后一行无效的关系运算符,不知道为什么 @SohamBanerjee 删除 order by 子句 - 在该子查询中不允许。而且,坦率地说,把它放在那里是没有意义的。 @NicholasKrasnov 但我需要检查现有的第一个服务是否有以前的记录(可能是非活动的)【参考方案2】:

您可以使用分析函数找到所有重复的行(无需进行第二次表扫描):

SELECT *
FROM   (
  SELECT r.*,
         ROW_NUMBER()
           OVER (
             PARTITION BY personalaccountid,
                          serviceid,
                          serviceline,
                          userserviceid,
                          servicerf
             ORDER BY     startdate
           ) as rn,
         COUNT( CASE WHEN masteraccountid = 'x' AND status = 30 THEN 1 END )
           OVER (
             PARTITION BY personalaccountid,
                          serviceid,
                          serviceline,
                          userserviceid,
                          servicerf
           ) as ct
  FROM   rlx_service_info r
)
WHERE ct > 0
AND   rn > 1;

如果您只想计算行数,请将外部查询更改为:

SELECT COUNT(*)
FROM   (
  SELECT COUNT( CASE WHEN masteraccountid = 'x' AND status = 30 THEN 1 END )
           OVER (
             PARTITION BY personalaccountid,
                          serviceid,
                          serviceline,
                          userserviceid,
                          servicerf
           ) as ct
  FROM   rlx_service_info r
)
WHERE  ct > 0;

【讨论】:

以上是关于查询返回 ORA-00936: 缺少表达式的主要内容,如果未能解决你的问题,请参考以下文章

ora:00936 缺少表达式错误

带有 ORA-00936 的 SQL 查询实例:缺少表达式错误

多维数据集 SQL ORA-00936 缺少表达式

ORA-00936: 缺少表达式

ORA-00936 缺少表达式

ORA 00936 缺少表达式