使用ORDER BY和ROWNUM进行查询时导致错误

时间:2016-01-21 03:02:52

标签: sql oracle hibernate oracle11g

我对ORM框架生成的查询有问题,以限制和排序Oracle Database 11.2.0.1.0 64位生产中的结果。生成的选择如下所示:

SELECT *
FROM
  (SELECT this_.*
   FROM plate this_
   WHERE this_.id IN 
      (SELECT DISTINCT this_.id AS y0_ FROM plate this_ )
   ORDER BY this_.name asc)
WHERE rownum <= 10;

尝试了解我创建以下沙箱的问题:

create table plate ( id integer primary key, 
                    name varchar2(30), 
                    description varchar2(255) );

insert into plate values ( 1, 'AAA-1234', 'test1' );
insert into plate values ( 2, 'BBB-1234', 'test2' );
insert into plate values ( 3, 'CCC-1234', 'test3' );
insert into plate values ( 4, 'DDD-1234', 'test4' );
commit;

在此示例中执行select,它返回:

id  name        description
1   DDD-1234    (null)
2   DDD-1234    (null)
3   DDD-1234    (null)
4   DDD-1234    (null)

根据我的理解,它应该返回:

id  name        description
1   AAA-1234    test1
2   BBB-1234    test2
3   CCC-1234    test3
4   DDD-1234    test4

有什么问题?为什么它没有回到我的预期呢?

编辑: 删除ORDER BY子句,它返回预期的结果。但为什么呢?

已编辑2: 执行计划如下:

---------------------------------------------------------------------------------
| Id  | Operation               | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |       |       |       |     4 (100)|          |
|*  1 |  COUNT STOPKEY          |       |       |       |            |          |
|   2 |   VIEW                  |       |     4 |   636 |     4  (25)| 00:00:01 |
|*  3 |    SORT ORDER BY STOPKEY|       |     4 |   636 |     4  (25)| 00:00:01 |
|   4 |     TABLE ACCESS FULL   | PLATE |     4 |   636 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(ROWNUM<=10)
   3 - filter(ROWNUM<=10)

Note
-----
   - dynamic sampling used for this statement (level=2)

2 个答案:

答案 0 :(得分:1)

在子查询中,有些东西对我来说很奇怪:

/* Styles go here */

input[type="checkbox"] {
  display: none;
}

.tech-green:before {
  content: "";
  display: inline-block;
  width: 30px;
  height: 30px;
  border-radius: 2px;
  background-color: rgba(29, 190, 96, 0.1);
  border: 1px solid #1DBE60;
  overflow:hidden;
}

input[type="checkbox"]:checked + .tech-green:before {
  color: #FFF;
  background-color: #1DBE60;
  content: "\2022";
  font-size: 20px;
  text-align: center;
  display:inline-block;
  overflow:hidden;
}

.tech-warn:before {
  content: "";
  display: inline-block;
  width: 30px;
  height: 30px;
  border-radius: 2px;
  background-color: rgba(240, 147, 29, 0.1);
  border: 1px solid #F0931D;
}

input[type="checkbox"]:checked + .tech-warn:before {
  color: #FFF;
  background-color: #F0931D;
  content: "\2022";
  font-size: 20px;
  text-align: center;
  display:inline-block;
  overflow:hidden;
}

this_ alias对两个不同的Selects使用两次。也许这会导致结果出错。 我不确定this_在order by子句中指向的是什么。 我不能保证这是你问题的原因,但对我来说似乎很奇怪。

答案 1 :(得分:0)

非常有趣......我发现这三种元素的组合会导致错误的结果:

  1. WHERE this_.id IN (SELECT...)
  2. 您在编辑中指出的
  3. ORDER BY 外部选择中的
  4. ROWNUM
  5. 如果省略上面列出的三个元素之一,一切正常。不知道甲骨文有什么困惑。为了维护查询的结构,我在子查询中使用ROW_NUMBER()而不是外部Select中的ROWNUM。这样:

    SELECT id, name, description
    FROM
        (SELECT this_.*, ROW_NUMBER() OVER(ORDER BY this_.name ASC) AS RN
         FROM plate this_
         WHERE this_.id IN 
           (SELECT DISTINCT this_.id AS y0_ FROM plate this_ )
        )
    WHERE rn <= 10
    ORDER BY rn asc;
    
相关问题