ROWNUM
Начиная с MariaDB 10.6.1, поддерживается функция ROWNUM().
Синтаксис
ROWNUM()
В режиме Oracle можно просто использовать ROWNUM, без скобок.
Описание
ROWNUM() возвращает текущее количество принятых строк в текущем контексте. Его основная цель — эмулировать псевдостолбец ROWNUM в Oracle. Для собственных приложений MariaDB рекомендуется использовать LIMIT, так как он проще в использовании и обеспечивает более предсказуемые результаты, чем использование ROWNUM().
Основное различие между использованием LIMIT и ROWNUM() для ограничения строк в результате заключается в том, что LIMIT работает со множеством результатов, а ROWNUM работает с количеством принятых строк (до применения любых ORDER или GROUP BY положений).
Следующие запросы вернут одинаковые результаты:
SELECT * from t1 LIMIT 10; SELECT * from t1 WHERE ROWNUM() <= 10;
В то время как следующие запросы могут возвращать разные результаты в зависимости от порядка нахождения строк:
SELECT * from t1 ORDER BY a LIMIT 10; SELECT * from t1 ORDER BY a WHERE ROWNUM() <= 10;
Рекомендуемый способ использования ROWNUM для ограничения количества возвращаемых строк и получения предсказуемых результатов — поместить запрос в подзапрос и проверить ROWNUM() во внешнем запросе:
SELECT * FROM (select * from t1 ORDER BY a) WHERE ROWNUM() <= 10;
ROWNUM() можно использовать в следующих контекстах:
При использовании в других контекстах, ROWNUM() вернёт 0.
Примеры
INSERT INTO t1 VALUES (1,ROWNUM()),(2,ROWNUM()),(3,ROWNUM()); INSERT INTO t1 VALUES (1),(2) returning a, ROWNUM(); UPDATE t1 SET row_num_column=ROWNUM(); DELETE FROM t1 WHERE a < 10 AND ROWNUM() < 2; LOAD DATA INFILE 'filename' into table t1 fields terminated by ',' lines terminated by "\r\n" (a,b) set c=ROWNUM();
Оптимизации
Во многих случаях, когда используется ROWNUM(), MariaDB будет использовать те же оптимизации, что и с LIMIT.
Оптимизация LIMIT возможна при использовании ROWNUM следующим образом:
- Когда вы находитесь в основном
WHEREпредложении, сравниваяROWNUM()с числовой константой, используя любое из следующих выражений:-
ROWNUM()< число -
ROWNUM()<= число -
ROWNUM()= 1ROWNUM()также может быть правым аргументом функции сравнения.
-
В указанных случаях оптимизация LIMIT может быть применена в следующих случаях:
- Для текущего подзапроса, когда сравнение ROWNUM выполняется на верхнем уровне:
SELECT * from t1 WHERE ROWNUM() <= 2 AND t1.a > 0
- Для внутреннего подзапроса, когда на верхнем уровне имеется только сравнение
ROWNUM()вWHEREпредложении:
SELECT * from (select * from t1) as t WHERE ROWNUM() <= 2
Другие изменения, связанные с ROWNUM
Когда ROWNUM() используется где-либо в запросе, оптимизация игнорирования ORDER BY в подзапросах отключается.
Это было сделано для правильной работы следующего распространенного запроса Oracle:
select * from (select * from t1 order by a desc) as t where rownum() <= 2;
По умолчанию MariaDB игнорирует любые ORDER BY в подзапросах, как потому, что стандарт SQL определяет наборы результатов в подзапросах как неупорядоченные, так и по причинам производительности (особенно при использовании представлений в подзапросах). См. MDEV-3926 "Неправильный результат с GROUP BY ... WITH ROLLUP" для обсуждения этой темы.
Другие соображения
Хотя MariaDB пытается как можно точнее эмулировать использование Oracle ROWNUM(), есть случаи, когда результат отличается:
- Когда оптимизатор находит строки в другом порядке (из-за разных методов хранения или оптимизации). Это также может произойти в Oracle, если вы добавите или удалите индекс, в этом случае строки могут быть найдены в другом порядке.
Обратите внимание, что использование ROWNUM() в функциях или хранимых процедурах будет использовать свой собственный контекст, а не контекст вызывающей стороны.
См. также
- MDEV-24089 поддержка синтаксиса oracle: rownum
- Оператор LIMIT
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/rownum/