ORA-00907:在Order by中缺少右括号提示

时间:2014-11-13 06:34:31

标签: sql oracle

在订购!!中缺少右括号提示

我想从sal_sale_fct获取最后一个amn_unit_pric_rial 每shp.DAT_CALCULATE,shp.COD_PROD_SAPRB 来自shp_inventory_fct 如果在sal_sale_fct中找不到行 返回sal_sale_fct

中最后一个日期的最后价格
select shp.DAT_CALCULATE,
      shp.COD_PROD_SAPRB,     
          (select sal.amn_unit_pric_rial
                  from sal_sale_fct sal 
                 where rownum = 1
                   and shp.cod_prod_saprb = sal.saprb_cod_prod_saprb
                   and shp.dat_calculate <= sal.dat_ord_ordhe
                   order by sal.dat_ord_ordhe
                   ) price
  From shp_inventory_fct shp

5 个答案:

答案 0 :(得分:3)

当你一起使用rownum和order时,首先评估rownum。第一行不会是sal.dat_ord_ordhe的顺序。因此,您需要先订购,然后使用rownum

选择第一行
select shp.DAT_CALCULATE,
  shp.COD_PROD_SAPRB,     
      (select price 
             (
             select sal.amn_unit_pric_rial price
              from sal_sale_fct sal 
             where shp.cod_prod_saprb = sal.saprb_cod_prod_saprb
               and shp.dat_calculate <= sal.dat_ord_ordhe
               order by sal.dat_ord_ordhe
               ) where  rownum = 1) Price
               From shp_inventory_fct shp

答案 1 :(得分:0)

我相信你不能在嵌套子查询中使用ORDER BY子句。尝试将您的查询更改为

select shp.DAT_CALCULATE,
      shp.COD_PROD_SAPRB,     
 sal.amn_unit_pric_rial
 from shp_inventory_fct shp 
 join sal_sale_fct sal 
 on shp.cod_prod_saprb = sal.saprb_cod_prod_saprb
 and shp.dat_calculate <= sal.dat_ord_ordhe
 order by sal.dat_ord_ordhe;

答案 2 :(得分:0)

我不知道出现此错误的原因,但即使您修复错误,我也不认为这会有效。我想你想要dat_ord_ordhe之后最接近shp.dat_calculate的行。 ORDER BY将在WHERE子句过滤结果后发生rownum = 1,因此您的SELECT dat_calculate, cod_prod_saprb, amn_unit_pric_rial FROM(SELECT shp.dat_calculate, shp.cod_prod_saprb, sal.amn_unit_pric_rial, ROW_NUMBER() OVER (PARTITION BY shp.dat_calculate, shp.cod_prod_saprb ORDER BY sal.dat_ord_ordhe) AS rank FROM shp_inventory_fct shp JOIN sal_sale_fct sal ON shp.cod_prod_saprb = sal.saprb_cod_prod_saprb AND shp.dat_calculate <= sal.dat_ord_ordhe ) WHERE rank = 1 将选择任何行而不是您想要的行。

也许这会有所帮助(但未经测试):

{{1}}

答案 3 :(得分:0)

无论如何order by都没有意义,因为即使您的查询有效,它也只会因为rownum = 1而返回一行。如果您希望记录包含max dat_ord_ord,则子查询应如下所示:

select shp.DAT_CALCULATE,
      shp.COD_PROD_SAPRB, 
   ( select sal.amn_unit_pric_rial
      from sal_sale_fct sal 
      where shp.cod_prod_saprb = sal.saprb_cod_prod_saprb
        and shp.dat_calculate <= sal.dat_ord_ordhe
        and rownum = 1
        and sal.dat_ord_ordhe = ( select max ( sal.dat_ord_ordhe )   
                                    from sal_sale_fct sal 
                                   where shp.cod_prod_saprb = sal.saprb_cod_prod_saprb
                                     and shp.dat_calculate <= sal.dat_ord_ordhe) ) price
From shp_inventory_fct shp

答案 4 :(得分:0)

ORA-00907几乎总是表示语法错误。这意味着Oracle在期望括号时遇到了关键字或其他内容。在这种情况下,它不是ORDER BY子句。

错误的原因是标量子查询必须只返回一行。 (你显然知道这一点,这就是为什么你有rownum=1)。如果结果集只有一行,那么排序就没有意义,因此Oracle会抛出任何错误。

现在您认为排序有一个原因,因为您希望子查询返回最新的amn_unit_pric_rial值。您的代码不会这样做,因为这不是ROWNUM()的工作方式。一旦查询获取了该行数,ROWNUM()就应用STOP COUNT操作;然后应用任何种类。因此rownum=1表示您的子查询只返回一个基本上随机的amn_unit_pric_rial值。

有多种方法可以解决这个问题,但是使用带有ROW_NUMBER()分析函数的子查询非常优雅,并且在大多数情况下应该表现良好。

with cte as 
   (
        select shp.dat_calculate
               , shp.cod_prod_saprb
               , sal.amn_unit_pric_rial
               , row_number() over (order by dat_ord_ordhe desc) rn
        from   shp_inventory_fct shp
               , sal_sale_fct sal 
        where shp.cod_prod_saprb = sal.saprb_cod_prod_saprb
        and shp.dat_calculate <= sal.dat_ord_ordhe
)
select dat_calculate
       , cod_prod_saprb
       , amn_unit_pric_rial as price
from cte
where  rn = 1                 
/

即使您有多条sal_sale_fct条记录具有相同的dat_ord_ordhe值,使用ROW_NUMBER也可以保证只获得一个结果。