Генерация номера строки без упорядочивания столбца

Я хочу сгенерировать номера строк в том же порядке, в котором добавляются данные. Приведенный ниже запрос отлично работает для SQL Server.

SELECT *,ROW_NUMBER() OVER (ORDER BY (SELECT 100)) AS SNO FROM TestTable

Мне нужен стандартный запрос для достижения того же сценария в Firebird. Кто-нибудь может подсказать мне об этом?

firebirdfaq.org/faq343
Arioch 'The 31.05.2018 11:00

попробуйте просто удалить пункт OVER(....). Или попробуйте OVER( ORDER BY 1 )firebirdsql.org/file/documentation/release_notes/html/en/3_0‌ /…

Arioch 'The 31.05.2018 11:04

это говорит о том, что Firebird 3 может иметь пустое предложение OVER: SELECT *,ROW_NUMBER() OVER () SNO FROM TestTable - см. firebird.1100200.n4.nabble.com/… - однако оконные функции, которые вы используете в ВАШЕМ примере запроса, были введены в SQL 2003 AFAIR, а не в SQL 92

Arioch 'The 31.05.2018 11:11

Возможный дубликат Номер строки в результате запроса

Arioch 'The 31.05.2018 11:11

Какую версию Firebird вы используете? Показанный запрос должен работать с Firebird 3.

Mark Rotteveel 31.05.2018 14:46

@MarkRotteveel нет, не должно - часть (SELECT 100) должна выйти из строя. И это требование по какой-то странной причине - это ANSI SQL 92, даже не сам Firebird. Иди разберись ...

Arioch 'The 31.05.2018 15:43

@ Arioch'The: В соответствии с вашими предложениями я попробовал запрос типа «SELECT *, ROW_NUMBER () OVER (ORDER BY 1) AS SNO FROM Orders». Он отлично работает с firebird. Но то же самое для SQL-сервера. Мне нужен стандартный (стандарт ANSI SQL) запрос для обоих случаев. Является ли это возможным? Пожалуйста, поправьте меня, если я неправильно понимаю.

Kavitha M 01.06.2018 06:46

Разве нельзя просто использовать ROW_NUMBER() OVER ()? Это должно работать в обоих и определено в стандарте SQL.

Mark Rotteveel 01.06.2018 08:18

@ Arioch'The я не заметил отсутствия стола там.

Mark Rotteveel 01.06.2018 08:19

@MarkRotteveel: Да. Указанный синтаксис не работает в sql. Я получил эту ошибку => «Функция 'ROW_NUMBER' должна иметь предложение OVER с ORDER BY.»

Kavitha M 01.06.2018 08:48
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
11
898
2

Ответы 2

Вы не можете использовать row_number() over (order by (select 100)) с Firebird, потому что Firebird - как того требует стандарт SQL - требует условия from для select. Эквивалент в Firebird будет row_number() over (order by (select 100 from rdb$database)).

Лучшим решением было бы использовать фактический столбец для order by, чтобы обеспечить детерминированный порядок.

Если посмотреть на стандарт SQL: 2016, то order by не требуется для row_number() (но он нужен для rank() и dense_rank()). К сожалению, похоже, что Microsoft применила это требование и для row_number(), возможно, для единообразия с функциями ранжирования, и, возможно, потому, что row_number() без заказа не имеет большого смысла. Использование row_number() over () с SQL Server дает ошибку «Функция 'row_number' должна иметь предложение OVER с ORDER BY.», но работает с Firebird.

SQL Server также требует, чтобы порядок в оконной функции не был ссылкой на числовой столбец. Использование row_number() over (order by 1) с SQL Server дает ошибку «Оконные функции, агрегаты и функции NEXT VALUE FOR не поддерживают целочисленные индексы в качестве выражений предложения ORDER BY»., но работает с Firebird (хотя 1 воспринимается как литерал 1, а не как ссылка на столбец, в отличие от order by на выбранном уровне).

SQL Server также не поддерживает использование констант или литералов в оконной функции в порядке следования. Использование row_number() over (order by '1') с SQL Server дает ошибку «Оконные функции, агрегаты и функции NEXT VALUE FOR не поддерживают константы как выражения предложения ORDER BY»., но работает с Firebird.

Я нашел трюк, который работал как с Firebird 3, так и с SQL Server 2017, но это грязный прием:

row_number() over (order by current_user)

Это работает, потому что SQL Server рассматривает current_user не как константу, а как функцию, что означает, что он не подпадает под правило «никаких констант не разрешено».

Имейте в виду, что этот трюк может привести к несогласованным номерам строк (например, в многооконных функциях Firebird, оцениваемых с помощью разных констант, будут получены разные значения, а оконная функция оценивается до order by на выбранном уровне), и вы можете подумать, не следует ли вам этого делать. t просто отслеживать индекс строки в вашем приложении.

Одним из способов могло быть использование ORDER BY RAND():

CREATE TABLE TestTable(i INT);
INSERT INTO TestTable(i) VALUES (10);
INSERT INTO TestTable(i) VALUES (20);
INSERT INTO TestTable(i) VALUES (30);

SELECT TestTable.*,ROW_NUMBER() OVER (ORDER BY RAND()) AS SNO 
FROM TestTable;

db <> демо скрипта - Firebird

db <> демонстрация скрипта - SQL Server

Другие вопросы по теме