【问题标题】:Query returns ORA-00936: missing expression查询返回 ORA-00936: 缺少表达式
【发布时间】: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 难怪我找不到文档...

标签: oracle


【解决方案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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    相关资源
    最近更新 更多