Skip to content
Oracle Database

Oracle Error ORA-01427

single-row subquery returns more than one row

Applies to: Oracle Database 19c, 21c, 23ai and 26ai (same wording in every release)
Last technically reviewed 24 October 2026 on Oracle Database Error Messages reference (26ai, 21c and 19c); not run locally
The full message
ORA-01427: single-row subquery returns more than one row
Other forms of this message
SQL*Plus and SQLcl show the failing line first
ERROR at line 1:
ORA-01427: single-row subquery returns more than one row
Error code
ORA-01427
Product
Oracle Database
Versions
Oracle Database 19c, 21c, 23ai and 26ai (same wording in every release)
Last reviewed
24 October 2026

What it means

ORA-01427 means a subquery used where only one value is allowed, such as after = or < or as a column in the SELECT list or an UPDATE ... SET, returned two or more rows when the statement ran.

A comparison such as WHERE customer_id = (SELECT ...), a scalar subquery in the SELECT list, and SET price = (SELECT ...) in an UPDATE all expect exactly one value. Oracle's reference says that when the subquery returns more than one row, the outer query must use ANY, ALL, IN or NOT IN instead, or the query must be reworded so only one row is retrieved.

The error is raised at run time and depends on the data: the same statement can work for months and then fail the day a second matching row is inserted. A subquery that returns no rows does not raise ORA-01427; in a comparison or as a scalar value it gives NULL. The message never says which subquery or which key returned several rows, so the diagnostics below find them.

Common causes

  • WHERE col = (SELECT ...) where the subquery can return several rows: a name, email or code that is not unique.
  • A scalar subquery in the SELECT list looks up one value per row, but the lookup table has duplicates for some keys.
  • UPDATE ... SET col = (SELECT ... WHERE key = outer.key) where the source table has more than one row per key.
  • The correlation condition is missing or incomplete, for example a subquery on order_lines correlated only by product and not by order.
  • A lookup table that used to be unique gained duplicates because it has no primary key or unique constraint on the lookup column.

Diagnose it

Read-only These queries only read the data dictionary (USER_, ALL_ and DBA_ views) and dynamic performance views (V$). They do not change data, privileges or settings, so they are safe to run first. DBA_ and V$ views need the matching privileges.

Run the subquery on its own

Take the subquery out and run it with a sample value from the outer query. More than one row confirms the cause.

SELECT customer_id
FROM shop.customers
WHERE name = 'Sara Ahmed';
What to look for

Two or more rows means = cannot compare against it. One row or none means this subquery is fine for that value; try others or check the next diagnostic.

Find the keys that return several rows

For a correlated subquery or an UPDATE ... SET, group the inner table by the correlation column(s).

SELECT sku, COUNT(*) AS copies
FROM shop.price_list
GROUP BY sku
HAVING COUNT(*) > 1
ORDER BY copies DESC;
What to look for

Each sku listed would make the subquery return several rows for that product. Decide which row is right (the latest, the active one) or remove the duplicates.

Is the lookup column declared unique?

SELECT c.constraint_name, c.constraint_type, cc.column_name
FROM all_constraints c
JOIN all_cons_columns cc
  ON cc.owner = c.owner AND cc.constraint_name = c.constraint_name
WHERE c.owner = 'SHOP'
  AND c.table_name = 'PRICE_LIST'
  AND c.constraint_type IN ('P', 'U');
What to look for

If no primary key or unique constraint covers the lookup column, nothing stops duplicates, and the subquery will keep failing whenever one appears.

How to fix it

Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.

Use IN (or ANY / ALL) when several rows are valid

Read-only

This is the first option in Oracle's Action text. IN matches any of the returned values.

SELECT order_id, amount
FROM shop.orders
WHERE customer_id IN (SELECT customer_id
                      FROM shop.customers
                      WHERE name = 'Sara Ahmed');

Make the subquery return one row on purpose

Read-only

When you want a single value, say which one: an aggregate such as MAX, or an ordered FETCH FIRST 1 ROW ONLY. Do not just add ROWNUM = 1 without ORDER BY: it returns an arbitrary row and hides the duplicates.

SELECT o.order_id,
       (SELECT p.price
        FROM shop.price_list p
        WHERE p.sku = o.sku
        ORDER BY p.valid_from DESC
        FETCH FIRST 1 ROW ONLY) AS current_price
FROM shop.order_lines o;

Complete the correlation condition

Read-only

Often the subquery is missing part of the key. Correlate on every column that identifies one row in the inner table.

SELECT o.order_id, o.sku,
       (SELECT p.price
        FROM shop.price_list p
        WHERE p.sku = o.sku
          AND p.currency = o.currency) AS price
FROM shop.order_lines o;

For updates, use MERGE with a unique source

Changes data

MERGE makes the source explicit. Reduce the source to one row per key first; MERGE itself raises ORA-30926 if a target row matches more than one source row.

MERGE INTO shop.products t
USING (SELECT sku, MAX(price) KEEP (DENSE_RANK LAST ORDER BY valid_from) AS price
       FROM shop.price_list
       GROUP BY sku) s
ON (t.sku = s.sku)
WHEN MATCHED THEN UPDATE SET t.price = s.price;

Stop new duplicates with a unique constraint

Changes schema

If the lookup column should be unique, declare it. Creating the constraint fails until existing duplicates are cleaned up (find them with the second diagnostic).

ALTER TABLE shop.price_list
  ADD CONSTRAINT price_list_sku_from_uk UNIQUE (sku, valid_from);

Examples

Comparing with = against a non-unique name

Not reproduced here: no Oracle Database is installed for this site. The result shows the message as documented in Oracle's error reference, which uses the same wording in 26ai, 21c and 19c. Changing = to IN returns the orders of both customers.

SELECT order_id, amount
FROM orders
WHERE customer_id = (SELECT customer_id
                     FROM customers
                     WHERE name = 'Sara Ahmed');
-- two customers are called Sara Ahmed
Expected result (documented format, not run)
ORA-01427: single-row subquery returns more than one row

An UPDATE whose source has two rows for one key

Not reproduced here: no Oracle Database is installed for this site. The message format is taken from Oracle's error reference. The whole UPDATE fails and no row is changed, even though most products have only one price.

UPDATE products p
SET price = (SELECT l.price
             FROM price_list l
             WHERE l.sku = p.sku);
-- price_list holds an old and a new price for sku 'A-100'
Expected result (documented format, not run)
ORA-01427: single-row subquery returns more than one row

How to prevent it

Before writing = (SELECT ...), check that the inner query is guaranteed to return one row by a primary key or unique constraint on the columns you filter by. If it is not, write IN, an aggregate or an ordered FETCH FIRST from the start.

Put unique constraints on lookup tables such as price lists and code tables, so a duplicate is rejected when it is inserted instead of breaking every query that reads it. See subqueries vs joins for when a join is clearer.

Common questions

How do I fix ORA-01427 single-row subquery returns more than one row?

Run the subquery alone to confirm it returns several rows, then either use IN, ANY or ALL if several values are valid, or make it return one row on purpose with an aggregate, a complete correlation condition or an ordered FETCH FIRST 1 ROW ONLY.

Why did a query that worked yesterday start failing?

ORA-01427 depends on the data. A new row made the subquery return two rows for some key. Find the duplicate keys with GROUP BY ... HAVING COUNT(*) > 1 and add a unique constraint if the column should be unique.

Is adding ROWNUM = 1 a good fix?

Only with care. ROWNUM = 1 without an ORDER BY returns whichever row Oracle reads first, which can change. Use an aggregate or ORDER BY ... FETCH FIRST 1 ROW ONLY so the chosen row is defined.

Learn more on CodeWithSQL

Official documentation

Last technically reviewed 24 October 2026; examples and diagnostics run on Oracle Database Error Messages reference (26ai, 21c and 19c); not run locally. Messages and explanations follow Oracle's Database Error Messages reference; no Oracle Database was available, so the examples were not run locally.

Still stuck on an Oracle error?

Browse the full Oracle error library, or get hands-on help from an experienced SQL professional.