У меня возникла проблема с запросом, сгенерированным инфраструктурой ORM, чтобы ограничить и упорядочить результаты в Oracle Database 11.2.0.1.0 64bit Production. Сформированные выберите выглядит следующим образом:Неверные результаты запроса с ORDER BY и ROWNUM
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;
Выполнение операции выбора в этом примере он возвращает:
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 возвращает ожидаемый результат. Но почему?
Edited 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)
Для меня запрос возвращает все четыре различных значения таблицы PLATES. Здесь нет ошибки. Следует сказать, что запрос имеет избыточную часть: «id IN (SELECT DISTINCT this_.id AS y0_ FROM plate this_)», который в этом случае ничего не делает. – diziaq
Кажется, что-то вроде ошибки в CBO, что вызывает неправильную переписку вашего запроса. Просто протестированный в 11.2.0.2.0 XE, он работает хорошо. Если бы вы могли опубликовать план выполнения, это было бы полезно. – Aleksej
@Aleksej План выполнения добавлен на вопрос. – Willian