Я хочу сгенерировать номера строк в том же порядке, в котором добавляются данные. Приведенный ниже запрос отлично работает для SQL Server.
SELECT *,ROW_NUMBER() OVER (ORDER BY (SELECT 100)) AS SNO FROM TestTable
Мне нужен стандартный запрос для достижения того же сценария в Firebird. Кто-нибудь может подсказать мне об этом?
попробуйте просто удалить пункт OVER(....). Или попробуйте OVER( ORDER BY 1 )firebirdsql.org/file/documentation/release_notes/html/en/3_0 /…
это говорит о том, что Firebird 3 может иметь пустое предложение OVER: SELECT *,ROW_NUMBER() OVER () SNO FROM TestTable - см. firebird.1100200.n4.nabble.com/… - однако оконные функции, которые вы используете в ВАШЕМ примере запроса, были введены в SQL 2003 AFAIR, а не в SQL 92
Возможный дубликат Номер строки в результате запроса
Какую версию Firebird вы используете? Показанный запрос должен работать с Firebird 3.
@MarkRotteveel нет, не должно - часть (SELECT 100) должна выйти из строя. И это требование по какой-то странной причине - это ANSI SQL 92, даже не сам Firebird. Иди разберись ...
@ Arioch'The: В соответствии с вашими предложениями я попробовал запрос типа «SELECT *, ROW_NUMBER () OVER (ORDER BY 1) AS SNO FROM Orders». Он отлично работает с firebird. Но то же самое для SQL-сервера. Мне нужен стандартный (стандарт ANSI SQL) запрос для обоих случаев. Является ли это возможным? Пожалуйста, поправьте меня, если я неправильно понимаю.
Разве нельзя просто использовать ROW_NUMBER() OVER ()? Это должно работать в обоих и определено в стандарте SQL.
@ Arioch'The я не заметил отсутствия стола там.
@MarkRotteveel: Да. Указанный синтаксис не работает в sql. Я получил эту ошибку => «Функция 'ROW_NUMBER' должна иметь предложение OVER с ORDER BY.»


Вы не можете использовать 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;