The NTH_VALUE window function received an invalid argument for the row position parameter. The second argument must be a positive integer greater than zero.
PostgreSQL error 22016 occurs when the NTH_VALUE window function is called with an invalid row position argument. The NTH_VALUE(expression, n) function requires the second parameter 'n' to be a positive integer (1, 2, 3, etc.). Common causes include passing zero, negative numbers, non-integer values, or incorrect data types for the position parameter.
Check your query for the NTH_VALUE function call. The correct syntax is:
NTH_VALUE(expression, n) OVER (
[PARTITION BY ...]
ORDER BY ...
[frame_clause]
)The second argument must be a positive integer that specifies which row to retrieve.
Check that the second argument to NTH_VALUE is a positive integer (greater than 0). If you're using a calculated value or variable, ensure it's converted to an integer.
-- Wrong: position is zero
SELECT NTH_VALUE(salary, 0) OVER (ORDER BY salary) FROM employees;
-- Correct: position is a positive integer
SELECT NTH_VALUE(salary, 2) OVER (ORDER BY salary) FROM employees;If you're using a calculated or variable row position, explicitly cast it to an integer:
-- If using a calculated position
SELECT NTH_VALUE(column_name, CAST(position_value AS INTEGER))
OVER (ORDER BY other_column)
FROM table_name;
-- Or use ::integer shorthand
SELECT NTH_VALUE(column_name, position_value::integer)
OVER (ORDER BY other_column)
FROM table_name;By default, PostgreSQL uses a frame that may not include the Nth row. Specify the frame explicitly to ensure the Nth row is included:
SELECT
employee_id,
salary,
NTH_VALUE(salary, 2) OVER (
ORDER BY salary DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS second_highest_salary
FROM employees;The frame specification ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ensures all rows are considered.
If the position comes from a nullable column or calculation, validate it before using:
SELECT
product_id,
price,
CASE
WHEN position_value > 0
THEN NTH_VALUE(price, position_value::integer) OVER (ORDER BY price)
ELSE NULL
END AS nth_price
FROM products;This prevents NULL or zero values from being passed to NTH_VALUE.
The NTH_VALUE function only considers rows within the current window frame, not the entire partition. By default, the frame is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, which may cause the function to return NULL if the Nth row hasn't been reached yet. Always specify an explicit frame clause (ROWS or RANGE) for predictable behavior. If N is greater than the number of rows in the frame, NTH_VALUE returns NULL, which is expected behavior and not an error condition. PostgreSQL does not implement the RESPECT NULLS/IGNORE NULLS or FROM FIRST/FROM LAST options from the SQL standard.
0LP01: invalid_grant_operation
How to fix "Invalid grant operation" (0LP01) in PostgreSQL
aggregate functions are not allowed in WHERE clause
How to fix "aggregate functions are not allowed in WHERE clause" in PostgreSQL
2200L: not_an_xml_document
How to fix "2200L: not_an_xml_document" in PostgreSQL
ERROR: ambiguous_parameter
42P08: Ambiguous parameter error
2201F: invalid_argument_for_power_function
Invalid argument for power function (2201F)