Oracle Complex View FAQs with Examples

A complex view is a view whose definition contains SQL features that make it more than a simple one-table projection. Common examples include joins, aggregate functions, GROUP BY, DISTINCT, set operators, and expressions.

Complex views are commonly used for reporting, data summarization, combining tables, and presenting business-specific data.

1. What is a complex view?

A complex view is generally a view based on:

  • Multiple tables
  • JOIN
  • Aggregate functions such as SUM, AVG, COUNT
  • GROUP BY
  • DISTINCT
  • Set operators such as UNION
  • More complicated expressions or subqueries

Example:

CREATE OR REPLACE VIEW emp_dept_view AS
SELECT e.employee_id,
       e.first_name,
       e.salary,
       d.department_name
FROM employees e
JOIN departments d
ON e.department_id = d.department_id;

This is a complex view because it combines:

EMPLOYEES
   +
DEPARTMENTS
   ↓
JOIN
   ↓
EMP_DEPT_VIEW

2. What is the difference between a simple view and a complex view?

Feature Simple View Complex View
Usually one table Not necessarily
Multiple tables ❌ Typically
JOIN ❌ Typically
GROUP BY
Aggregate functions
DISTINCT
Set operators
Reporting use Sometimes Very common
Directly updatable Often Often not

Easy way to remember:

Simple View
   ↓
One table
   ↓
Straightforward data

Complex View
   ↓
Multiple tables / calculations / aggregation
   ↓
Reporting or business logic

3. Why do we use complex views?

Complex views are useful when you want to hide complicated SQL from users.

Instead of users writing:

SELECT e.employee_id,
       e.first_name,
       d.department_name,
       e.salary
FROM employees e
JOIN departments d
ON e.department_id = d.department_id
WHERE e.salary > 50000;

you can create:

CREATE OR REPLACE VIEW high_paid_emp_dept AS
SELECT e.employee_id,
       e.first_name,
       d.department_name,
       e.salary
FROM employees e
JOIN departments d
ON e.department_id = d.department_id
WHERE e.salary > 50000;

Users can simply run:

SELECT *
FROM high_paid_emp_dept;

4. Can a complex view use multiple tables?

Yes. This is one of the most common examples.

CREATE OR REPLACE VIEW emp_dept_details AS
SELECT e.employee_id,
       e.first_name,
       e.salary,
       d.department_name
FROM employees e
JOIN departments d
ON e.department_id = d.department_id;

Now:

SELECT *
FROM emp_dept_details;

might produce:

EMPLOYEE_ID  FIRST_NAME  SALARY  DEPARTMENT_NAME
-----------  ----------  ------  ---------------
101          JOHN        60000   IT
102          SMITH       70000   HR
103          JANE        80000   SALES

5. Can a complex view use GROUP BY?

Yes.

CREATE OR REPLACE VIEW dept_salary_summary AS
SELECT department_id,
       COUNT(*) AS employee_count,
       SUM(salary) AS total_salary,
       AVG(salary) AS average_salary
FROM employees
GROUP BY department_id;

Query:

SELECT *
FROM dept_salary_summary;

Example result:

DEPARTMENT_ID  EMPLOYEE_COUNT  TOTAL_SALARY  AVERAGE_SALARY
-------------  --------------  ------------  --------------
10             5               350000        70000
20             8               640000        80000
30             4               300000        75000

This is clearly a complex view because it summarizes multiple rows into groups.

6. Can a complex view use aggregate functions?

Yes.

Common aggregate functions include:

COUNT()
SUM()
AVG()
MIN()
MAX()

Example:

CREATE OR REPLACE VIEW dept_salary AS
SELECT department_id,
       MIN(salary) AS min_salary,
       MAX(salary) AS max_salary,
       AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;

7. Can a complex view use DISTINCT?

Yes.

CREATE OR REPLACE VIEW employee_departments AS
SELECT DISTINCT department_id
FROM employees;

Query:

SELECT *
FROM employee_departments;

The DISTINCT removes duplicate department IDs.

Because the result doesn't necessarily correspond one-to-one with individual base-table rows, this type of view is generally not directly updatable.

8. Can a complex view use UNION?

Yes.

CREATE OR REPLACE VIEW all_people AS
SELECT employee_id AS person_id,
       first_name AS person_name
FROM employees

UNION

SELECT customer_id AS person_id,
       customer_name AS person_name
FROM customers;

Now:

SELECT *
FROM all_people;

combines data from two sources.

EMPLOYEES
    ↓
SELECT
    ↓
UNION
    ↑
SELECT
    ↑
CUSTOMERS

9. Can a complex view use UNION ALL?

Yes.

CREATE OR REPLACE VIEW all_people AS
SELECT employee_id AS person_id,
       first_name AS person_name
FROM employees

UNION ALL

SELECT customer_id AS person_id,
       customer_name AS person_name
FROM customers;

Difference:

UNION
→ removes duplicates

UNION ALL
→ keeps duplicates

10. Can a complex view use calculated columns?

Yes.

CREATE OR REPLACE VIEW employee_salary_details AS
SELECT employee_id,
       first_name,
       salary,
       salary * 12 AS annual_salary,
       salary * 12 * 0.10 AS estimated_bonus
FROM employees;

Query:

SELECT *
FROM employee_salary_details;

Possible output:

EMPLOYEE_ID  FIRST_NAME  SALARY  ANNUAL_SALARY  ESTIMATED_BONUS
-----------  ----------  ------  -------------  ---------------
101          JOHN        50000   600000         60000

The calculated columns are expressions rather than stored base-table columns.

11. Are complex views updatable?

Generally, complex views are not directly updatable.

For example:

CREATE OR REPLACE VIEW dept_summary AS
SELECT department_id,
       COUNT(*) AS employee_count,
       AVG(salary) AS average_salary
FROM employees
GROUP BY department_id;

Trying:

UPDATE dept_summary
SET average_salary = 70000
WHERE department_id = 10;

doesn't make sense as a normal direct update because AVERAGE_SALARY is calculated from multiple employee rows.

Oracle therefore doesn't treat this as a normal directly updatable view.

12. Why are aggregate views generally not updatable?

Consider:

SELECT department_id,
       AVG(salary)
FROM employees
GROUP BY department_id;

Suppose department 10 has:

Employee A → 50,000
Employee B → 70,000
Employee C → 90,000

The view contains:

Department 10 → 70,000 average

If someone says:

UPDATE view
SET average_salary = 80000;

which employee should Oracle change?

Employee A? Employee B? Employee C? All three?

There isn't a unique row mapping. That's why aggregate views are generally not directly updatable.

13. Can a complex view contain a JOIN and still be updatable?

Some join views can be partially updatable, depending on the view definition and which table/columns are being modified.

CREATE OR REPLACE VIEW emp_dept_view AS
SELECT e.employee_id,
       e.first_name,
       e.salary,
       d.department_name
FROM employees e
JOIN departments d
ON e.department_id = d.department_id;

The view combines two tables, so you shouldn't assume that every DML operation against it will work.

For interview purposes:

A join view is a complex view, and its DML capabilities depend on Oracle's updatability rules.

14. What is a key-preserved table?

This is an important Oracle interview concept for complex views.

A table is key-preserved when each row from that table can appear at most once in the result of the join.

Example:

SELECT e.employee_id,
       e.first_name,
       d.department_name
FROM employees e
JOIN departments d
ON e.department_id = d.department_id;

If DEPARTMENTS.DEPARTMENT_ID is unique/primary key, each employee can match only one department.

Therefore, EMPLOYEES can potentially be key-preserved in the join.

15. Why is key preservation important?

It helps Oracle determine whether an update can be mapped unambiguously to rows in an underlying table.

For example:

UPDATE emp_dept_view
SET salary = salary + 1000
WHERE employee_id = 101;

If Oracle can uniquely identify the corresponding EMPLOYEES row, updating that column may be possible.

But attempting to modify columns from a non-key-preserved table can produce errors such as:

ORA-01779:
cannot modify a column which maps to a non key-preserved table

16. Can a complex view contain subqueries?

Yes.

CREATE OR REPLACE VIEW above_avg_employees AS
SELECT employee_id,
       first_name,
       salary
FROM employees
WHERE salary > (
    SELECT AVG(salary)
    FROM employees
);

Query:

SELECT *
FROM above_avg_employees;

This returns employees whose salary is above the company-wide average.

17. Can a complex view contain a HAVING clause?

Yes.

CREATE OR REPLACE VIEW large_departments AS
SELECT department_id,
       COUNT(*) AS employee_count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 10;

Now:

SELECT *
FROM large_departments;

returns only departments with more than 10 employees.

18. Can a complex view use multiple aggregate functions?

Yes.

CREATE OR REPLACE VIEW dept_statistics AS
SELECT department_id,
       COUNT(*) AS employee_count,
       SUM(salary) AS total_salary,
       AVG(salary) AS avg_salary,
       MIN(salary) AS min_salary,
       MAX(salary) AS max_salary
FROM employees
GROUP BY department_id;

This is a common reporting view.

19. Can a complex view contain CASE expressions?

Yes.

CREATE OR REPLACE VIEW employee_salary_category AS
SELECT employee_id,
       first_name,
       salary,
       CASE
           WHEN salary >= 100000 THEN 'HIGH'
           WHEN salary >= 50000  THEN 'MEDIUM'
           ELSE 'LOW'
       END AS salary_category
FROM employees;

Query:

SELECT *
FROM employee_salary_category;

Example:

EMPLOYEE_ID  FIRST_NAME  SALARY  SALARY_CATEGORY
-----------  ----------  ------  ---------------
101          JOHN        120000  HIGH
102          SMITH        70000   MEDIUM
103          JANE        40000   LOW

20. Can a complex view contain functions?

Yes.

CREATE OR REPLACE VIEW employee_display AS
SELECT employee_id,
       UPPER(first_name) AS employee_name,
       ROUND(salary, -3) AS rounded_salary
FROM employees;

You can use Oracle functions such as:

UPPER()
LOWER()
ROUND()
TRUNC()
NVL()
COALESCE()
CASE

and many others.

21. Can a complex view use multiple joins?

Yes.

CREATE OR REPLACE VIEW employee_full_details AS
SELECT e.employee_id,
       e.first_name,
       d.department_name,
       l.city,
       l.country
FROM employees e
JOIN departments d
ON e.department_id = d.department_id
JOIN locations l
ON d.location_id = l.location_id;

Conceptually:

EMPLOYEES
    |
    +---- DEPARTMENTS
    |
    +---- LOCATIONS
    |
    ↓
EMPLOYEE_FULL_DETAILS

This is a typical complex reporting view.

22. Can a complex view use outer joins?

Yes.

CREATE OR REPLACE VIEW emp_dept_details AS
SELECT e.employee_id,
       e.first_name,
       d.department_name
FROM employees e
LEFT JOIN departments d
ON e.department_id = d.department_id;

The LEFT JOIN ensures that employees without a matching department can still appear.

23. Can a complex view use INNER JOIN?

Yes.

CREATE OR REPLACE VIEW emp_dept_details AS
SELECT e.employee_id,
       e.first_name,
       d.department_name
FROM employees e
INNER JOIN departments d
ON e.department_id = d.department_id;

Only employees with matching departments appear.

24. Can a complex view use ORDER BY?

Oracle allows ORDER BY in certain view definitions depending on the query and Oracle version/context, but you should not rely on a view to guarantee output ordering.

Prefer:

SELECT *
FROM emp_dept_details
ORDER BY first_name;

The outermost query should specify the desired ordering.

25. Can a complex view be read-only?

Yes.

CREATE OR REPLACE VIEW dept_summary AS
SELECT department_id,
       COUNT(*) AS employee_count,
       AVG(salary) AS average_salary
FROM employees
GROUP BY department_id
WITH READ ONLY;

Now users can:

SELECT *
FROM dept_summary;

but cannot perform DML through the view.

26. What is WITH READ ONLY?

It explicitly makes the view read-only.

CREATE OR REPLACE VIEW employee_report AS
SELECT e.employee_id,
       e.first_name,
       d.department_name,
       e.salary
FROM employees e
JOIN departments d
ON e.department_id = d.department_id
WITH READ ONLY;

Attempting:

UPDATE employee_report
SET salary = 60000
WHERE employee_id = 101;

will fail.

This is useful for reporting views.

27. What is WITH CHECK OPTION?

WITH CHECK OPTION ensures that rows modified through a view continue to satisfy the view's WHERE condition.

For example:

CREATE OR REPLACE VIEW dept10_employees AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees
WHERE department_id = 10
WITH CHECK OPTION;

This:

UPDATE dept10_employees
SET department_id = 20
WHERE employee_id = 101;

is rejected because the resulting row would no longer belong to department 10.

However, WITH CHECK OPTION doesn't magically make a complex aggregate view updatable.

28. Can we insert into a complex view?

Usually not directly, especially when the view contains:

  • GROUP BY
  • Aggregate functions
  • DISTINCT
  • Set operators
  • Certain joins
  • Other constructs that prevent unambiguous mapping

For example:

CREATE VIEW dept_summary AS
SELECT department_id,
       COUNT(*) AS employee_count
FROM employees
GROUP BY department_id;

This isn't an appropriate target for:

INSERT INTO dept_summary ...

29. Can we delete from a complex view?

Again, it depends on the view definition.

A view containing aggregation such as:

SELECT department_id,
       COUNT(*)
FROM employees
GROUP BY department_id;

is not directly deletable in the normal sense.

There is no single employee row corresponding to:

Department 10 → COUNT = 25

30. How can we make a complex view updatable?

One common solution is an INSTEAD OF trigger.

Suppose we have:

CREATE OR REPLACE VIEW emp_dept_view AS
SELECT e.employee_id,
       e.first_name,
       e.salary,
       d.department_name
FROM employees e
JOIN departments d
ON e.department_id = d.department_id;

You can use an INSTEAD OF trigger to control what happens when users perform DML against the view.

Example:

CREATE OR REPLACE TRIGGER trg_emp_dept_update
INSTEAD OF UPDATE ON emp_dept_view
FOR EACH ROW
BEGIN

    UPDATE employees
    SET salary = :NEW.salary
    WHERE employee_id = :OLD.employee_id;

END;
/

Now:

UPDATE emp_dept_view
SET salary = 75000
WHERE employee_id = 101;

causes the trigger to update the underlying EMPLOYEES table.

UPDATE VIEW
    ↓
INSTEAD OF TRIGGER
    ↓
UPDATE EMPLOYEES

31. What is a reporting view?

A reporting view is a common type of complex view designed to simplify reports.

CREATE OR REPLACE VIEW department_report AS
SELECT d.department_name,
       COUNT(e.employee_id) AS employee_count,
       NVL(SUM(e.salary), 0) AS total_salary,
       NVL(AVG(e.salary), 0) AS average_salary
FROM departments d
LEFT JOIN employees e
ON d.department_id = e.department_id
GROUP BY d.department_name;

Users can simply run:

SELECT *
FROM department_report;

Instead of repeatedly writing the complicated query.

32. What is a business-rule view?

A complex view can hide business logic.

Example:

CREATE OR REPLACE VIEW employee_status_report AS
SELECT employee_id,
       first_name,
       salary,
       CASE
           WHEN salary >= 100000 THEN 'EXECUTIVE'
           WHEN salary >= 75000  THEN 'SENIOR'
           WHEN salary >= 50000  THEN 'MID_LEVEL'
           ELSE 'JUNIOR'
       END AS employee_level
FROM employees;

Now applications don't need to repeat the salary classification logic.

33. Can a complex view improve security?

Yes.

Suppose users shouldn't see every column in the underlying tables.

You can expose only the required information:

CREATE OR REPLACE VIEW employee_report AS
SELECT e.employee_id,
       e.first_name,
       d.department_name,
       e.salary
FROM employees e
JOIN departments d
ON e.department_id = d.department_id;

Then:

GRANT SELECT
ON employee_report
TO reporting_user;

The user can access the view without necessarily receiving direct access to all underlying tables/columns.

34. Does a complex view store data?

No.

A normal complex view doesn't store the query result as physical rows.

For example:

CREATE VIEW dept_summary AS
SELECT department_id,
       COUNT(*) AS employee_count
FROM employees
GROUP BY department_id;

The view stores the definition. The result is generated when queried.

Normal Complex View
        ↓
Query definition
        ↓
Underlying tables
        ↓
Result

If you need a physically stored result, consider a materialized view.

35. Complex view vs materialized view

Feature Complex View Materialized View
Stores query definition
Stores query result
Refresh required
Can use aggregation
Can use joins
Useful for reporting
Result physically stored

Example normal view:

CREATE VIEW dept_summary AS
SELECT department_id,
       COUNT(*)
FROM employees
GROUP BY department_id;

Materialized view:

CREATE MATERIALIZED VIEW dept_summary_mv
BUILD IMMEDIATE
REFRESH COMPLETE
ON DEMAND
AS
SELECT department_id,
       COUNT(*)
FROM employees
GROUP BY department_id;

36. How do I check view definitions?

Use USER_VIEWS:

SELECT view_name,
       text
FROM user_views
ORDER BY view_name;

For a particular view:

SELECT text
FROM user_views
WHERE view_name = 'EMP_DEPT_VIEW';

37. How do I check whether view columns are updatable?

Oracle provides:

USER_UPDATABLE_COLUMNS

Example:

SELECT table_name,
       column_name,
       insertable,
       updatable,
       deletable
FROM user_updatable_columns
WHERE table_name = 'EMP_DEPT_VIEW';

This is especially useful when investigating a complex join view.

38. What are common complex-view errors?

One important error is:

ORA-01779:
cannot modify a column which maps to a non key-preserved table

This can occur when attempting to modify a column through a join view where Oracle cannot uniquely map the view row to a base-table row.

Another common situation is trying to perform DML against an aggregate view:

UPDATE dept_summary
SET employee_count = 10;

Such a view isn't normally directly updatable.

39. Can a complex view depend on another view?

Yes.

Example:

CREATE OR REPLACE VIEW emp_dept_view AS
SELECT e.employee_id,
       e.first_name,
       d.department_name
FROM employees e
JOIN departments d
ON e.department_id = d.department_id;

Then:

CREATE OR REPLACE VIEW emp_report AS
SELECT employee_id,
       first_name,
       department_name
FROM emp_dept_view
WHERE department_name = 'IT';

Dependency chain:

EMPLOYEES
    ↓
EMP_DEPT_VIEW
    ↓
EMP_REPORT

40. What happens if an underlying table changes?

A normal view doesn't contain a separate stored copy of the data.

If:

UPDATE employees
SET salary = salary + 5000
WHERE employee_id = 101;

then querying a view based on EMPLOYEES reflects the changed underlying data.

However, if you change the structure of the underlying tables, the view may become invalid or require recompilation, depending on the change.

You can inspect object status with:

SELECT object_name,
       status
FROM user_objects
WHERE object_type = 'VIEW';

41. How do you create a complex view step by step?

Step 1: Create the base tables

CREATE TABLE departments (
    department_id   NUMBER PRIMARY KEY,
    department_name VARCHAR2(100)
);
CREATE TABLE employees (
    employee_id   NUMBER PRIMARY KEY,
    first_name    VARCHAR2(100),
    salary        NUMBER,
    department_id NUMBER
);

Step 2: Create the complex view

CREATE OR REPLACE VIEW department_report AS
SELECT d.department_id,
       d.department_name,
       COUNT(e.employee_id) AS employee_count,
       SUM(e.salary) AS total_salary,
       AVG(e.salary) AS average_salary
FROM departments d
LEFT JOIN employees e
ON d.department_id = e.department_id
GROUP BY d.department_id,
         d.department_name;

Step 3: Query it

SELECT *
FROM department_report;

Possible result:

DEPARTMENT_ID  DEPARTMENT_NAME  EMPLOYEE_COUNT  TOTAL_SALARY  AVERAGE_SALARY
-------------  ---------------  --------------  ------------  --------------
10             IT               5               350000        70000
20             HR               3               210000        70000
30             SALES            8               640000        80000

This is a classic complex reporting view.

42. Simple View vs Complex View — Interview Example

Simple view

CREATE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

Characteristics:

  • One table
  • No aggregation
  • No GROUP BY
  • Direct columns
  • Often updatable

Complex view

CREATE VIEW emp_dept_summary AS
SELECT d.department_name,
       COUNT(e.employee_id) AS employee_count,
       AVG(e.salary) AS average_salary
FROM departments d
JOIN employees e
ON d.department_id = e.department_id
GROUP BY d.department_name;

Characteristics:

  • Multiple tables
  • JOIN
  • COUNT()
  • AVG()
  • GROUP BY
  • Generally read-only for direct DML

43. What are the most common complex-view interview traps?

Trap 1

Can a complex view have a JOIN?

✅ Yes.

Trap 2

Can a complex view have GROUP BY?

✅ Yes.

Trap 3

Can a complex view have aggregate functions?

✅ Yes.

Trap 4

Is every complex view read-only?

❌ Not necessarily.

Some join views can support certain DML operations depending on Oracle's updatability rules.

Trap 5

Are aggregate views normally updatable?

❌ No.

Trap 6

Can an INSTEAD OF trigger make DML possible on a complex view?

✅ Yes.

This is a very important technique.

Trap 7

Does a normal complex view store data?

❌ No.

A normal view stores its query definition, not a materialized copy of the result.

Trap 8

Does a complex view require refresh?

❌ No.

That's a materialized-view concept.

44. Complex View Cheat Sheet

COMPLEX VIEW
    |
    +------------+------------+
    |            |            |
   JOIN        GROUP BY     DISTINCT
    |            |            |
 Multiple      Aggregate     Remove
 tables        results      duplicates
    |            |            |
    +------------+------------+
                 |
                 ↓
          Complex Query
                 |
                 ↓
            VIEW RESULT

Common complex-view components:

  • JOIN
  • GROUP BY
  • HAVING
  • COUNT()
  • SUM()
  • AVG()
  • MIN()
  • MAX()
  • DISTINCT
  • UNION
  • UNION ALL
  • Subqueries
  • CASE
  • Calculated columns
  • Multiple tables

Key Interview Statement

A complex view is a view whose query contains more advanced SQL constructs—such as joins, aggregation, GROUP BY, DISTINCT, or set operators—and is commonly used to simplify reporting and business logic. Unlike a simple view, it is not necessarily directly updatable.

And the most important distinction:

Simple View
    ↓
Usually one table
    ↓
Direct row mapping
    ↓
Often updatable

Complex View
    ↓
JOIN / GROUP BY / aggregate / DISTINCT / UNION
    ↓
Result may not map to one base row
    ↓
Usually not directly updatable
    ↓
INSTEAD OF trigger can sometimes provide DML behavior

Oracle Simple View FAQs with Examples

A simple view is a view based primarily on one base table, without features such as GROUP BY, aggregate functions, DISTINCT, or set operators. Simple views are especially important because they are often updatable.

1. What is a simple view?

A simple view is a view created from a single table using a relatively straightforward SELECT.

CREATE OR REPLACE VIEW emp_simple_view AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees;

Now:

SELECT *
FROM emp_simple_view;

Conceptually:

EMPLOYEES
    |
    ↓
EMP_SIMPLE_VIEW
    |
    ↓
SELECT

The view normally doesn't store a separate copy of the employee rows.

2. Why is it called a simple view?

It is called "simple" because the view definition is relatively uncomplicated.

Simple View
    ↓
One base table
    ↓
No GROUP BY
No aggregate functions
No DISTINCT
No UNION
No complex calculations

Example:

CREATE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

3. What is the syntax for creating a simple view?

CREATE [OR REPLACE] VIEW view_name AS
SELECT column1,
       column2,
       ...
FROM table_name
WHERE condition;

Example:

CREATE OR REPLACE VIEW high_salary_emp AS
SELECT employee_id,
       first_name,
       salary
FROM employees
WHERE salary > 100000;

4. Does a simple view store data?

No, not as a separate copy of the data.

For example:

CREATE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

The data remains in:

EMPLOYEES
   ↓
  data
   ↓
EMP_VIEW
   ↓
query definition

5. Can a simple view contain a WHERE clause?

Yes.

CREATE OR REPLACE VIEW active_employees AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees
WHERE status = 'ACTIVE';

Query:

SELECT *
FROM active_employees;

Only rows satisfying:

status = 'ACTIVE'

are displayed.

6. Can we update a simple view?

Yes, provided the view is updatable.

CREATE OR REPLACE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

You can potentially do:

UPDATE emp_view
SET salary = salary + 1000
WHERE employee_id = 101;

The underlying table is actually updated:

UPDATE VIEW
     ↓
EMPLOYEES
     ↓
Row updated

7. Can we insert through a simple view?

Yes, if the view is insertable and the required underlying columns are satisfied.

CREATE OR REPLACE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees;

Then:

INSERT INTO emp_view
(
    employee_id,
    first_name,
    salary,
    department_id
)
VALUES
(
    101,
    'John',
    50000,
    10
);

The row is inserted into EMPLOYEES.

8. Can we delete through a simple view?

Yes, if the view is deletable.

DELETE FROM emp_view
WHERE employee_id = 101;

The corresponding row is deleted from:

EMPLOYEES

9. Why are simple views often updatable?

Because there is generally a clear one-to-one relationship between a row in the view and a row in the underlying table.

CREATE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

A view row:

101 | John | 50000

corresponds directly to an underlying employee row. Therefore Oracle can determine which base-table row should be modified.

10. Can a simple view contain a WHERE condition and still be updated?

Yes.

CREATE VIEW sales_employees AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees
WHERE department_id = 10;

You may be able to update:

UPDATE sales_employees
SET salary = salary + 1000
WHERE employee_id = 101;

The underlying EMPLOYEES row is updated.

But there is an important issue when changing the columns used by the view condition.

11. What is WITH CHECK OPTION in a simple view?

WITH CHECK OPTION prevents DML through the view from producing rows that no longer satisfy the view's WHERE condition.

CREATE OR REPLACE VIEW sales_employees AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees
WHERE department_id = 10
WITH CHECK OPTION;

Now this is rejected:

UPDATE sales_employees
SET department_id = 20
WHERE employee_id = 101;

Why?

Because after the update:

department_id = 20

The row would no longer satisfy:

department_id = 10

Remember:

WITH CHECK OPTION
        ↓
"You can modify the row,
but it must remain visible through the view."

12. What happens without WITH CHECK OPTION?

Consider:

CREATE VIEW sales_employees AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees
WHERE department_id = 10;

You may perform:

UPDATE sales_employees
SET department_id = 20
WHERE employee_id = 101;

The underlying row can be changed to department 20.

After the update:

SELECT *
FROM sales_employees
WHERE employee_id = 101;

may return no row because the employee no longer satisfies:

department_id = 10

This is why WITH CHECK OPTION is useful.

13. Can a simple view contain calculated columns?

This needs care.

CREATE VIEW emp_salary_view AS
SELECT employee_id,
       first_name,
       salary,
       salary * 12 AS annual_salary
FROM employees;

This is still based on one table, but ANNUAL_SALARY is a derived expression.

The derived column itself isn't directly updatable:

UPDATE emp_salary_view
SET annual_salary = 1000000;

is not a normal direct update of a base-table column.

So, for interview purposes, the safest definition of a simple updatable view is:

A view based on a single table that exposes directly mappable base-table columns and doesn't contain constructs that prevent direct modification.

14. Can a simple view contain DISTINCT?

Technically, a view can be created using DISTINCT, but it is not considered a simple updatable view in the usual Oracle terminology.

CREATE VIEW dept_view AS
SELECT DISTINCT department_id
FROM employees;

This is not a straightforward row-for-row representation of EMPLOYEES.

Therefore:

DISTINCT
   ↓
Generally not directly updatable

15. Can a simple view contain GROUP BY?

A view can contain GROUP BY, but then it is generally considered a complex view, not a simple view.

CREATE VIEW dept_summary AS
SELECT department_id,
       COUNT(*) AS employee_count
FROM employees
GROUP BY department_id;

This is a complex/aggregate view.

16. Can a simple view contain aggregate functions?

A view can contain them, but it is no longer a simple updatable view.

CREATE VIEW salary_summary AS
SELECT department_id,
       AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;

The AVG() value isn't stored as an individual base-table column.

Therefore, Oracle cannot simply determine which employee row should be updated if you attempt:

UPDATE salary_summary
SET avg_salary = 70000;

17. Can a simple view contain a JOIN?

A view can contain a JOIN, but that generally makes it a complex view.

CREATE VIEW emp_dept_view AS
SELECT e.employee_id,
       e.first_name,
       d.department_name
FROM employees e
JOIN departments d
ON e.department_id = d.department_id;

This is not the typical definition of a simple view because it uses multiple tables.

18. Simple View vs Complex View

Feature Simple View Complex View
One base table Not necessarily
Multiple tables ❌ Typically
JOIN ❌ Typically
GROUP BY
Aggregate functions
DISTINCT
Set operators
Often updatable Often ❌

Easy memory trick:

Simple View
    ↓
One table
    ↓
Direct columns
    ↓
Usually easy to update


Complex View
    ↓
JOIN / GROUP BY / DISTINCT / aggregates
    ↓
Usually not directly updatable

19. Can we create a read-only simple view?

Yes.

CREATE OR REPLACE VIEW emp_readonly AS
SELECT employee_id,
       first_name,
       salary
FROM employees
WITH READ ONLY;

You can query it:

SELECT *
FROM emp_readonly;

But DML through the view is prohibited.

UPDATE emp_readonly
SET salary = 60000
WHERE employee_id = 101;

This fails because the view is read-only.

20. WITH CHECK OPTION vs WITH READ ONLY

Feature WITH CHECK OPTION WITH READ ONLY
SELECT
INSERT Potentially
UPDATE Potentially
DELETE Potentially
Enforces view WHERE condition N/A
Allows DML

Remember:

CHECK OPTION
→ DML allowed, but view condition must remain true

READ ONLY
→ No DML through the view

21. Can a simple view hide columns?

Yes. This is one of the most useful applications.

Suppose:

EMPLOYEES
----------------
EMPLOYEE_ID
FIRST_NAME
SALARY
SSN
BANK_ACCOUNT

Create:

CREATE OR REPLACE VIEW employee_public AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

Now users accessing the view don't see:

SSN
BANK_ACCOUNT

You can grant access to the view:

GRANT SELECT
ON employee_public
TO reporting_user;

This is useful for security and controlled data exposure.

22. Can we rename columns in a simple view?

Yes.

CREATE OR REPLACE VIEW employee_info AS
SELECT employee_id AS emp_id,
       first_name AS employee_name,
       salary AS monthly_salary
FROM employees;

Now:

SELECT *
FROM employee_info;

returns:

EMP_ID
EMPLOYEE_NAME
MONTHLY_SALARY

23. Can we explicitly specify view column names?

Yes.

CREATE OR REPLACE VIEW employee_info
(
    emp_id,
    employee_name,
    monthly_salary
)
AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

The view columns become:

EMP_ID
EMPLOYEE_NAME
MONTHLY_SALARY

24. What happens if we insert into a simple view that doesn't contain all base-table columns?

It depends on the underlying table.

Suppose:

CREATE TABLE employees (
    employee_id NUMBER,
    first_name VARCHAR2(50),
    salary NUMBER,
    department_id NUMBER NOT NULL
);

And the view is:

CREATE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

Now:

INSERT INTO emp_view
VALUES (101, 'John', 50000);

The insert may fail because DEPARTMENT_ID is required and isn't supplied through the view.

So:

A view being simple/updatable doesn't mean every possible INSERT will succeed. Underlying constraints still apply.

25. Can a simple view be used for security?

Yes.

CREATE OR REPLACE VIEW employee_public AS
SELECT employee_id,
       first_name,
       department_id
FROM employees;

Grant:

GRANT SELECT
ON employee_public
TO app_user;

The application can use:

SELECT *
FROM employee_public;

instead of having direct access to all columns in EMPLOYEES.

26. How do I find simple views in my schema?

Oracle's data dictionary doesn't provide a simple IS_SIMPLE_VIEW flag that you should rely on for all cases.

You can inspect views using:

SELECT view_name,
       text
FROM user_views
ORDER BY view_name;

For example:

SELECT view_name
FROM user_views;

Then inspect the definitions to determine whether they contain joins, aggregation, set operations, etc.

27. What is USER_UPDATABLE_COLUMNS?

Oracle provides dictionary information about whether columns in views are updatable.

Example:

SELECT owner,
       table_name,
       column_name,
       insertable,
       updatable,
       deletable
FROM user_updatable_columns
WHERE table_name = 'EMP_VIEW';

This can help determine whether DML is allowed for columns exposed by a view.

Example result conceptually:

COLUMN_NAME      INSERTABLE  UPDATABLE  DELETABLE
----------------------------------------------------
EMPLOYEE_ID      YES         YES        YES
FIRST_NAME       YES         YES        YES
SALARY           YES         YES        YES

This is particularly useful when analyzing view updatability.

28. What is the difference between a simple view and a table?

Feature Table Simple View
Physically stores rows
Based on another object Not necessarily
Stores query definition
Can have indexes
Can hide columns Through privileges
Can be queried
Can be updated Often ✅

29. What is the difference between a simple view and a materialized view?

Feature Simple View Materialized View
Stores query definition
Stores query result
Refresh required
FAST refresh
Physical rows
Can have indexes on result
Primary purpose Abstraction/security Performance/reporting

Think:

SIMPLE VIEW
Query → Base table → Result


MATERIALIZED VIEW
Query → Stored result
          ↑
        Refresh

30. What happens when the underlying table changes?

Because a normal view doesn't contain a separate copy of the data, querying the view normally reflects the current underlying table data.

Example:

CREATE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

Then:

UPDATE employees
SET salary = 75000
WHERE employee_id = 101;

Now:

SELECT *
FROM emp_view
WHERE employee_id = 101;

will reflect the updated salary.

There is no separate view refresh operation for a normal view.

31. Does a simple view need to be refreshed?

No.

This is an important distinction:

Normal View
    ↓
No refresh


Materialized View
    ↓
Refresh required to synchronize stored results

For example:

SELECT *
FROM emp_view;

always queries the underlying data according to the view definition.

32. Can we create a simple view using CREATE OR REPLACE?

Yes.

CREATE OR REPLACE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees;

This replaces the existing view definition if the view already exists.

33. Does replacing a simple view delete table data?

No.

For:

CREATE OR REPLACE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

Oracle changes the view definition. It doesn't delete rows from:

EMPLOYEES

34. How do I drop a simple view?

Use:

DROP VIEW emp_view;

This removes:

EMP_VIEW

but does not remove:

EMPLOYEES
or its rows.

35. Can a simple view be used in another query?

Absolutely.

SELECT employee_id,
       first_name
FROM emp_view
WHERE salary > 50000
ORDER BY salary DESC;

The view behaves like a table from the perspective of the query.

36. Can we create a view based on a view?

Yes.

CREATE OR REPLACE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees;

Then:

CREATE OR REPLACE VIEW high_paid_emp AS
SELECT employee_id,
       first_name,
       salary
FROM emp_view
WHERE salary > 100000;

Conceptually:

EMPLOYEES
    ↓
EMP_VIEW
    ↓
HIGH_PAID_EMP

Although possible, avoid unnecessarily deep chains of views because they can make dependency and performance analysis more complicated.

37. Can a simple view contain a subquery?

A view can contain a subquery, but once the definition becomes more complex, it may no longer fit the practical definition of a simple updatable view.

For example:

CREATE VIEW high_paid_emp AS
SELECT employee_id,
       first_name,
       salary
FROM employees
WHERE salary > (
    SELECT AVG(salary)
    FROM employees
);

This is a valid view, but don't classify every one-table view as automatically updatable merely because it references one table.

38. Can we use ORDER BY in a simple view?

The safest practice is to put ordering in the query that reads the view:

SELECT *
FROM emp_view
ORDER BY salary DESC;

Don't rely on a view to guarantee presentation order.

39. What are the most common simple-view interview questions?

Question 1: What is a simple view?

A view generally based on a single table without constructs such as joins, grouping, aggregation, DISTINCT, or set operators that make direct row modification difficult.

Question 2: Is a simple view always updatable?

❌ No. A simple view is often updatable, but actual updatability depends on its definition and the DML operation.

Question 3: Can we update a simple view?

✅ Often yes.

UPDATE emp_view
SET salary = salary + 1000
WHERE employee_id = 101;

Question 4: Can a simple view hide columns?

✅ Yes.

CREATE VIEW emp_public AS
SELECT employee_id,
       first_name
FROM employees;

Question 5: Can a simple view have a WHERE clause?

✅ Yes.

Question 6: Does a simple view store data?

❌ No, not as a separate result set.

Question 7: Does a simple view need refresh?

❌ No.

Question 8: Can a simple view have WITH CHECK OPTION?

✅ Yes.

Question 9: What is WITH READ ONLY?

It prevents DML through the view.

Question 10: What is the difference between a simple and complex view?

Simple
→ usually one table
→ straightforward columns
→ often updatable

Complex
→ joins / aggregation / GROUP BY / DISTINCT / set operations
→ often not directly updatable

40. Simple View Complete Example

Let's put everything together.

Base table

CREATE TABLE employees (
    employee_id   NUMBER PRIMARY KEY,
    first_name    VARCHAR2(50),
    salary        NUMBER,
    department_id NUMBER,
    status        VARCHAR2(20)
);

Create simple view

CREATE OR REPLACE VIEW active_emp_view AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees
WHERE status = 'ACTIVE'
WITH CHECK OPTION;

Query

SELECT *
FROM active_emp_view;

Update

UPDATE active_emp_view
SET salary = salary + 1000
WHERE employee_id = 101;

Attempt to move row outside the view

Whether a column can be modified through a view depends on whether that column is exposed by the view. Since STATUS isn't exposed here, this particular statement cannot directly modify it through the view.

Instead, attempting to change an exposed view predicate column illustrates the CHECK OPTION behavior:

CREATE OR REPLACE VIEW dept10_emp AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees
WHERE department_id = 10
WITH CHECK OPTION;

Then:

UPDATE dept10_emp
SET department_id = 20
WHERE employee_id = 101;

is rejected because the resulting row would violate the view condition.

41. Simple View Cheat Sheet

CREATE VIEW
    ↓
Create view

CREATE OR REPLACE VIEW
    ↓
Replace definition

SELECT FROM view
    ↓
Read view

UPDATE view
    ↓
Possible if updatable

INSERT INTO view
    ↓
Possible if insertable

DELETE FROM view
    ↓
Possible if deletable

WITH CHECK OPTION
    ↓
DML must satisfy view condition

WITH READ ONLY
    ↓
No DML through view

DROP VIEW
    ↓
Remove view only

The Key Concept to Remember

SIMPLE VIEW
       ↓
Usually one table
       ↓
Direct base columns
       ↓
No GROUP BY / aggregate
       ↓
No DISTINCT / UNION
       ↓
Often directly updatable
Interview One-Liner: A simple view in Oracle is a view based on a single table with a straightforward column mapping, generally without joins, aggregation, GROUP BY, DISTINCT, or set operators, and it is often directly updatable.

Oracle Views FAQs with Examples

An Oracle view is a virtual table based on the result of a SQL query.

A normal view generally does not store the query result as separate data. Instead, Oracle stores the view definition, and when you query the view, Oracle retrieves the underlying data.

Think:

Base Tables
↓
SELECT
↓
VIEW
↓
User queries the VIEW

1. What is a view in Oracle?

A view is a named SQL query that behaves like a table when queried.

Example:

CREATE OR REPLACE VIEW emp_details AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees;

Now you can query:

SELECT *
FROM emp_details;

Instead of repeatedly writing:

SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees;

2. Does a view store data?

For a normal view, generally no.

The view stores the SQL definition:

VIEW
↓
SQL query definition
↓
Underlying table data

For example:

CREATE VIEW emp_view AS
SELECT employee_id, salary
FROM employees;

The rows are still stored in:

EMPLOYEES

not separately in:

EMP_VIEW

Important distinction

VIEW
→ virtual table

MATERIALIZED VIEW
→ stores query result physically

3. What is the basic syntax for creating a view?

CREATE [OR REPLACE] VIEW view_name AS
SELECT ...
FROM ...;

Example:

CREATE VIEW high_salary_emp AS
SELECT employee_id,
       first_name,
       salary
FROM employees
WHERE salary > 100000;

Query:

SELECT *
FROM high_salary_emp;

4. Why do we use views?

Common reasons include:

5. Simplify complex SQL

CREATE VIEW emp_dept_details AS
SELECT e.employee_id,
       e.first_name,
       e.salary,
       d.department_name
FROM employees e
JOIN departments d
ON e.department_id = d.department_id;

Instead of repeatedly writing the join:

SELECT *
FROM emp_dept_details;

6. Security

You can expose only selected columns:

CREATE VIEW employee_public AS
SELECT employee_id,
       first_name,
       department_id
FROM employees;

Users don't need direct access to every column in EMPLOYEES.

7. Hide implementation details

Users can work with:

EMP_DEPT_DETAILS

without knowing the underlying joins.

8. Can a view contain a WHERE clause?

Yes.

Example:

CREATE VIEW active_employees AS
SELECT employee_id,
       first_name,
       salary
FROM employees
WHERE status = 'ACTIVE';

Then:

SELECT *
FROM active_employees;

Only active employees are returned.

9. Can a view contain a JOIN?

Yes.

Example:

CREATE VIEW employee_department AS
SELECT e.employee_id,
       e.first_name,
       d.department_name
FROM employees e
JOIN departments d
ON e.department_id = d.department_id;

Query:

SELECT *
FROM employee_department;

10. Can a view contain multiple tables?

Yes.

Example:

CREATE VIEW employee_details AS
SELECT e.employee_id,
       e.first_name,
       d.department_name,
       l.city
FROM employees e
JOIN departments d
ON e.department_id = d.department_id
JOIN locations l
ON d.location_id = l.location_id;

A view can be based on complex queries involving multiple tables.

11. Can a view contain aggregate functions?

Yes.

For example:

CREATE VIEW dept_salary_summary AS
SELECT department_id,
       COUNT(*) AS employee_count,
       SUM(salary) AS total_salary,
       AVG(salary) AS average_salary
FROM employees
GROUP BY department_id;

Query:

SELECT *
FROM dept_salary_summary;

Result conceptually:

DEPARTMENT_ID  EMPLOYEE_COUNT  TOTAL_SALARY  AVERAGE_SALARY
-------------  --------------  ------------  --------------
10             5               300000        60000
20             8               600000        75000
30             4               280000        70000

12. Can a view contain GROUP BY?

Yes.

Example:

CREATE VIEW dept_summary AS
SELECT department_id,
       COUNT(*) AS employee_count
FROM employees
GROUP BY department_id;

However, views containing grouping and aggregation are generally not directly updatable.

13. Can a view contain ORDER BY?

Oracle has restrictions depending on the query and usage. In general, you should not rely on a view's row order.

For example, rather than assuming:

SELECT *
FROM emp_view;

will return rows in a particular order, use:

SELECT *
FROM emp_view
ORDER BY salary DESC;

Interview point

A view does not guarantee the ordering of rows.

The ORDER BY should normally be specified in the query that consumes the view when ordering matters.

14. What is a simple view?

A simple view is generally based on a single table and doesn't contain features such as aggregation or grouping that prevent straightforward row modification.

Example:

CREATE VIEW emp_simple AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

This is a typical simple view.

15. What is a complex view?

A complex view generally contains things such as:

  • Multiple tables
  • Joins
  • Aggregate functions
  • GROUP BY
  • DISTINCT
  • Calculated expressions

Example:

CREATE VIEW emp_dept_summary AS
SELECT d.department_id,
       d.department_name,
       COUNT(e.employee_id) AS employee_count,
       AVG(e.salary) AS avg_salary
FROM departments d
JOIN employees e
ON d.department_id = e.department_id
GROUP BY d.department_id,
         d.department_name;

This is a complex view.

16. What is the difference between simple and complex views?

Feature Simple View Complex View
Usually based on one table Not necessarily
Multiple tables Usually no
JOIN Usually no
GROUP BY Usually no
Aggregate functions Usually no
DISTINCT Usually no
Often directly updatable Often ❌

The exact updatability rules depend on the view definition.

17. Can we INSERT into a view?

Sometimes.

Example:

CREATE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees;

If the view is updatable, you may be able to:

INSERT INTO emp_view
(
    employee_id,
    first_name,
    salary,
    department_id
)
VALUES
(
    101,
    'John',
    50000,
    10
);

The insert affects the underlying table:

INSERT INTO VIEW
↓
Underlying EMPLOYEES table

18. Can we UPDATE a view?

Yes, if the view is updatable.

Example:

UPDATE emp_view
SET salary = 60000
WHERE employee_id = 101;

The underlying table is modified.

Conceptually:

UPDATE VIEW
↓
EMPLOYEES
↓
Row updated

19. Can we DELETE from a view?

Yes, if the view is deletable.

Example:

DELETE FROM emp_view
WHERE employee_id = 101;

The corresponding row is deleted from the underlying table.

20. When is a view not directly updatable?

Views containing certain constructs generally aren't directly modifiable.

Common examples include:

  • GROUP BY
  • DISTINCT
  • Aggregate functions
  • UNION
  • UNION ALL
  • Set operators

For example:

CREATE VIEW dept_summary AS
SELECT department_id,
       COUNT(*) AS employee_count
FROM employees
GROUP BY department_id;

This isn't a normal row-by-row updatable view.

You cannot simply do:

UPDATE dept_summary
SET employee_count = 10;

because employee_count is derived from an aggregate.

21. What is WITH CHECK OPTION?

WITH CHECK OPTION ensures that DML performed through a view doesn't create rows that fall outside the view's defining condition.

Example:

CREATE VIEW high_salary_emp AS
SELECT employee_id,
       first_name,
       salary
FROM employees
WHERE salary >= 100000
WITH CHECK OPTION;

Now:

UPDATE high_salary_emp
SET salary = 50000
WHERE employee_id = 101;

Oracle rejects the operation because the resulting row would no longer satisfy:

salary >= 100000

Without WITH CHECK OPTION, an update through an updatable view can potentially move a row outside the view's result set.

22. What is WITH READ ONLY?

WITH READ ONLY prevents DML through the view.

Example:

CREATE VIEW emp_read_only AS
SELECT employee_id,
       first_name,
       salary
FROM employees
WITH READ ONLY;

You can:

SELECT *
FROM emp_read_only;

But DML through the view is prohibited:

UPDATE emp_read_only
SET salary = 60000
WHERE employee_id = 101;

The view is intended for querying only.

23. WITH CHECK OPTION vs WITH READ ONLY

Feature WITH CHECK OPTION WITH READ ONLY
SELECT
INSERT Can be allowed
UPDATE Can be allowed
DELETE Can be allowed
Enforces view condition N/A
Prevents all DML

Remember:

CHECK OPTION → DML allowed, but must obey view condition

READ ONLY → No DML through view

24. What is CREATE OR REPLACE VIEW?

It allows you to replace the existing view definition.

Example:

CREATE OR REPLACE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees;

If EMP_VIEW already exists, Oracle replaces its definition.

This is commonly used when modifying a view.

25. Does replacing a view delete the underlying table data?

No.

For example:

CREATE OR REPLACE VIEW emp_view AS
SELECT employee_id, salary
FROM employees;

Replacing the view changes the view definition, not the underlying EMPLOYEES data.

26. Can a view reference another view?

Yes.

Example:

CREATE VIEW active_employees AS
SELECT employee_id,
       first_name,
       salary
FROM employees
WHERE status = 'ACTIVE';

Then:

CREATE VIEW high_paid_active_employees AS
SELECT employee_id,
       first_name,
       salary
FROM active_employees
WHERE salary > 100000;

So:

EMPLOYEES
↓
ACTIVE_EMPLOYEES
↓
HIGH_PAID_ACTIVE_EMPLOYEES

However, excessive layers of views can make SQL harder to understand and optimize.

27. Can a view reference a materialized view?

Yes.

A view can use a materialized view as one of its underlying objects, provided the necessary privileges and dependencies are satisfied.

Example:

CREATE VIEW sales_report AS
SELECT *
FROM mv_sales_summary;

28. Can a view have calculated columns?

Yes.

Example:

CREATE VIEW emp_salary_details AS
SELECT employee_id,
       first_name,
       salary,
       salary * 12 AS annual_salary
FROM employees;

Query:

SELECT *
FROM emp_salary_details;

Result:

EMPLOYEE_ID  FIRST_NAME  SALARY  ANNUAL_SALARY
-----------  ----------  ------  -------------
101          John        50000   600000
102          Mary        60000   720000

ANNUAL_SALARY is derived from the underlying data.

29. Can a view hide sensitive columns?

Yes. This is a common security use case.

Suppose:

EMPLOYEES
----------------
EMPLOYEE_ID
FIRST_NAME
SALARY
BANK_ACCOUNT
SSN

Create:

CREATE VIEW employee_public AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

Users can be granted access to the view instead of the base table.

GRANT SELECT ON employee_public TO reporting_user;

This allows controlled exposure of columns.

30. Does creating a view automatically give users access to the underlying tables?

No.

The owner of the view needs appropriate privileges on referenced objects, and other users need privileges on the view.

For example:

GRANT SELECT ON employee_public TO reporting_user;

The user can query:

SELECT *
FROM employee_public;

without necessarily receiving direct SELECT access to EMPLOYEES.

31. What happens if the underlying table is dropped?

The view's dependency on the table is broken.

For example:

DROP TABLE employees;

A view depending on EMPLOYEES becomes invalid.

You can check object status using:

SELECT object_name,
       object_type,
       status
FROM user_objects
WHERE object_type = 'VIEW';

32. What happens if a column used by a view is changed?

The view can become invalid depending on the type of change.

For example:

CREATE VIEW emp_view AS
SELECT employee_id,
       salary
FROM employees;

If the underlying structure changes incompatibly, Oracle may invalidate the view.

Check:

SELECT object_name,
       status
FROM user_objects
WHERE object_type = 'VIEW';

33. How can I see all views in my schema?

Use:

SELECT view_name
FROM user_views;

For example:

SELECT view_name
FROM user_views
ORDER BY view_name;

34. How can I see the definition of a view?

Use:

SELECT view_name,
       text
FROM user_views
WHERE view_name = 'EMP_VIEW';

You can also inspect the source through Oracle's dictionary views depending on your privileges and needs.

35. What is USER_VIEWS?

USER_VIEWS contains information about views owned by the current user.

Example:

SELECT view_name
FROM user_views;

Common columns include information about:

VIEW_NAME
TEXT

36. What is the difference between USER_VIEWS, ALL_VIEWS, and DBA_VIEWS?

View Shows
USER_VIEWS Views owned by current user
ALL_VIEWS Views accessible to current user
DBA_VIEWS Views in the database, requiring appropriate privileges

Example:

SELECT view_name
FROM user_views;

37. How do I rename a view?

Oracle supports:

RENAME old_view TO new_view;

Example:

RENAME emp_view TO employee_view;

However, be careful with dependent objects, application code, synonyms, and grants.

38. How do I drop a view?

Use:

DROP VIEW emp_view;

This removes the view definition.

It does not delete data from the underlying table.

Example:

DROP VIEW
↓
VIEW removed

EMPLOYEES
↓
Data remains

39. What is the difference between DROP VIEW and DROP TABLE?

Drop view

DROP VIEW emp_view;

Removes:

VIEW

but leaves:

EMPLOYEES

Drop table

DROP TABLE employees;

Removes the underlying table and its data, subject to Oracle's DDL behavior and dependencies.

40. Can a view contain a subquery?

Yes.

Example:

CREATE VIEW high_salary_emp AS
SELECT employee_id,
       first_name,
       salary
FROM employees
WHERE salary >
      (SELECT AVG(salary)
       FROM employees);

This displays employees earning above the average salary.

41. Can a view use UNION?

Yes.

Example:

CREATE VIEW all_customers AS
SELECT customer_id,
       customer_name
FROM domestic_customers

UNION

SELECT customer_id,
       customer_name
FROM international_customers;

Such a view is generally not directly updatable because of the set operation.

42. Can a view contain DISTINCT?

Yes.

Example:

CREATE VIEW employee_departments AS
SELECT DISTINCT department_id
FROM employees;

Query:

SELECT *
FROM employee_departments;

Because DISTINCT changes the row mapping between the view and base table, such a view is generally not directly updatable.

43. Can we create an index on a normal view?

No.

You cannot normally create an index directly on a conventional view.

For example:

CREATE INDEX idx_emp_view
ON emp_view(salary);

is not how normal views are indexed.

Instead, indexes belong to the underlying tables.

For example:

CREATE INDEX idx_emp_salary
ON employees(salary);

Important distinction

VIEW
↓
No stored rows
↓
No normal index on the view itself

MATERIALIZED VIEW
↓
Stores rows
↓
Can have indexes

44. Does a view improve query performance?

Not automatically.

A normal view is primarily a logical abstraction.

For example:

CREATE VIEW emp_view AS
SELECT *
FROM employees
WHERE department_id = 10;

Then:

SELECT *
FROM emp_view;

doesn't inherently make the query faster just because it uses a view.

Oracle's optimizer can often merge or transform view queries during optimization.

For performance, consider:

  • Appropriate indexes
  • Good SQL
  • Statistics
  • Partitioning
  • Materialized views where appropriate

45. View vs Materialized View

This is a very common interview question.

Feature View Materialized View
Stores query definition
Stores query result ❌ Generally no
Data physically stored
Needs refresh
Can use FAST refresh
Can improve reporting performance Sometimes Often
Can have indexes on stored result

Think:

VIEW
Query → underlying tables → result

MATERIALIZED VIEW
Query → stored result
↓
refresh

46. View vs Table

Feature Table View
Stores data ❌ Normally
Stores query definition
Can contain joins Data structure doesn't
Can hide columns Via privileges
Can be queried with SELECT
Can always be updated Depends on constraints Depends on view
Requires refresh

47. What is an inline view?

An inline view is a subquery in the FROM clause.

Example:

SELECT *
FROM (
    SELECT employee_id,
           first_name,
           salary
    FROM employees
    WHERE salary > 50000
);

The inner query is an inline view.

Important distinction:

CREATE VIEW
↓
Database object

Inline view
↓
Subquery used inside SQL statement

48. What is an updatable view?

An updatable view is a view through which Oracle can perform DML against the underlying table.

Example:

CREATE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

Then potentially:

UPDATE emp_view
SET salary = salary + 1000
WHERE employee_id = 101;

The underlying EMPLOYEES row is updated.

49. What is a read-only view?

Example:

CREATE VIEW emp_readonly AS
SELECT employee_id,
       first_name,
       salary
FROM employees
WITH READ ONLY;

You can:

SELECT *
FROM emp_readonly;

But not:

DELETE FROM emp_readonly;

or:

UPDATE emp_readonly
SET salary = 50000;

50. What is a view with WITH CHECK OPTION?

Example:

CREATE VIEW sales_emp AS
SELECT employee_id,
       first_name,
       salary
FROM employees
WHERE department_id = 10
WITH CHECK OPTION;

Now:

UPDATE sales_emp
SET department_id = 20
WHERE employee_id = 101;

is rejected because the updated row would no longer satisfy:

department_id = 10

Think:

WITH CHECK OPTION
↓
"You can modify through the view,
but the resulting row must remain
visible through the view."

51. What is a force view?

Oracle allows:

CREATE FORCE VIEW my_view AS
SELECT *
FROM future_table;

FORCE tells Oracle to create the view even if referenced objects aren't currently valid/available, subject to Oracle's rules.

Example:

CREATE FORCE VIEW emp_future AS
SELECT employee_id
FROM employees_future;

If EMPLOYEES_FUTURE doesn't exist, the view can be created as an invalid object.

Later, after the dependency is created:

CREATE TABLE employees_future (
    employee_id NUMBER
);

the view can potentially be revalidated.

Compare:

CREATE VIEW
↓
Referenced objects must be valid

CREATE FORCE VIEW
↓
Allow creation even when dependencies aren't currently valid

52. What is NO FORCE?

NO FORCE is the default behavior for CREATE VIEW.

Example:

CREATE NO FORCE VIEW emp_view AS
SELECT *
FROM employees;

Oracle requires the referenced objects to be valid enough for the view to be created.

53. What is a common security use case for views?

Suppose a table contains:

EMPLOYEES
----------------
EMPLOYEE_ID
NAME
SALARY
SSN
BANK_ACCOUNT

You want reporting users to see:

EMPLOYEE_ID
NAME
DEPARTMENT

Create:

CREATE VIEW employee_report AS
SELECT employee_id,
       first_name,
       department_id
FROM employees;

Then:

GRANT SELECT
ON employee_report
TO reporting_user;

The user can query:

SELECT *
FROM employee_report;

This gives you a controlled interface over the underlying table.

54. What happens if the underlying table has new columns?

Suppose:

CREATE VIEW emp_view AS
SELECT *
FROM employees;

Later:

ALTER TABLE employees
ADD email VARCHAR2(200);

Do not assume that an existing SELECT * view automatically behaves exactly like a newly created SELECT * query.

A key best practice is:

Explicitly specify columns in production views.

Prefer:

CREATE VIEW emp_view AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees;

instead of relying on:

SELECT *

This makes the view definition clearer and more stable.

55. Can we create a view with column aliases?

Yes.

Example:

CREATE VIEW employee_info AS
SELECT employee_id AS emp_id,
       first_name AS employee_name,
       salary AS monthly_salary
FROM employees;

Query:

SELECT *
FROM employee_info;

Result columns:

EMP_ID
EMPLOYEE_NAME
MONTHLY_SALARY

56. Can we explicitly specify view column names?

Yes.

Example:

CREATE VIEW employee_info
(
    emp_id,
    employee_name,
    monthly_salary
)
AS
SELECT employee_id,
       first_name,
       salary
FROM employees;

Now the view columns are:

EMP_ID
EMPLOYEE_NAME
MONTHLY_SALARY

57. Can a view have constraints?

A normal view doesn't have table-style storage constraints such as primary keys in the same sense as a base table.

However, Oracle supports certain view constraints for query optimization and integrity-related metadata in appropriate contexts.

For most interview purposes, remember:

Base table → actual data + table constraints

View → logical query result

58. Can we create a synonym for a view?

Yes.

Example:

CREATE SYNONYM emp
FOR employee_view;

Then:

SELECT *
FROM emp;

The synonym points to the view.

59. Can a view be used in a stored procedure?

Yes.

Example:

CREATE OR REPLACE PROCEDURE show_employees
IS
BEGIN
    FOR r IN (
        SELECT employee_id,
               first_name
        FROM emp_view
    )
    LOOP
        DBMS_OUTPUT.PUT_LINE(
            r.employee_id || ' ' || r.first_name
        );
    END LOOP;
END;
/

A view can be used anywhere an appropriate table/query source can be used.

60. Can a view be used in a trigger?

Yes.

For example, a trigger can query a suitable view, subject to the usual trigger restrictions.

However, be careful with dependencies and mutating-table situations when the view ultimately references the table currently being modified.

61. Can a view be used with another view in a JOIN?

Yes.

Example:

SELECT e.employee_id,
       e.first_name,
       d.department_name
FROM employee_view e
JOIN department_view d
ON e.department_id = d.department_id;

Oracle's optimizer can often transform the resulting query.

62. What happens when a view becomes INVALID?

Check:

SELECT object_name,
       status
FROM user_objects
WHERE object_type = 'VIEW';

If:

STATUS
------
INVALID

the underlying dependency has changed or become unavailable.

Oracle may recompile the view when appropriate, or you can explicitly compile it:

ALTER VIEW emp_view COMPILE;

Then check again:

SELECT object_name,
       status
FROM user_objects
WHERE object_name = 'EMP_VIEW';

63. How do I compile an invalid view?

Use:

ALTER VIEW emp_view COMPILE;

Then:

SELECT object_name,
       status
FROM user_objects
WHERE object_name = 'EMP_VIEW';

64. What are common Oracle View interview traps?

Trap 1

Does a normal view store data?

❌ Generally no.

Trap 2

Can every view be updated?

❌ No.
Updatability depends on the view definition.

Trap 3

Can a view have a JOIN?

✅ Yes.

Trap 4

Can a view have GROUP BY?

✅ Yes.
But such a view is generally not directly updatable.

Trap 5

Can a view have an index?

❌ A normal view doesn't have indexes like a table.
A materialized view can have indexes because it stores data.

Trap 6

Does a view improve performance automatically?

❌ No.
A view is primarily a logical abstraction.

Trap 7

Does dropping a view delete the base-table data?

❌ No.

Trap 8

What does WITH CHECK OPTION do?

It ensures DML through an updatable view doesn't create a row that violates the view's defining condition.

Trap 9

What does WITH READ ONLY do?

Prevents DML through the view.

Trap 10

View vs Materialized View?

VIEW
→ virtual/logical result

MATERIALIZED VIEW
→ physically stored result that can be refreshed

65. Simple real-world example

Suppose you have:

CREATE TABLE employees (
    employee_id   NUMBER PRIMARY KEY,
    first_name    VARCHAR2(50),
    salary        NUMBER,
    department_id NUMBER,
    status        VARCHAR2(20)
);

Create a view for active employees:

CREATE OR REPLACE VIEW active_employee_view AS
SELECT employee_id,
       first_name,
       salary,
       department_id
FROM employees
WHERE status = 'ACTIVE';

Query:

SELECT *
FROM active_employee_view;

Create a more restricted version:

CREATE OR REPLACE VIEW active_employee_public AS
SELECT employee_id,
       first_name,
       department_id
FROM employees
WHERE status = 'ACTIVE'
WITH CHECK OPTION;

Now the view provides:

EMPLOYEES
|
+----------------------+
|                      |
↓                      ↓
ACTIVE_EMPLOYEE_VIEW   ACTIVE_EMPLOYEE_PUBLIC
|                      |
↓                      ↓
Internal users         Restricted users

66. View vs Materialized View vs Table

Feature Table View Materialized View
Stores data
Stores query definition
Virtual result
Refresh required
Can use FAST refresh
Can have indexes
Good for security abstraction Possible ✅ Excellent Possible
Good for precomputed reporting

67. Final Oracle View Cheat Sheet

CREATE VIEW
↓
Create virtual table

CREATE OR REPLACE VIEW
↓
Replace view definition

WITH READ ONLY
↓
No DML through view

WITH CHECK OPTION
↓
DML must keep row within view condition

CREATE FORCE VIEW
↓
Allow creation when dependencies aren't currently valid

DROP VIEW
↓
Remove view, not base-table data

ALTER VIEW ... COMPILE
↓
Recompile invalid view

Most important commands

-- Create
CREATE VIEW emp_view AS
SELECT employee_id, first_name, salary
FROM employees;

-- Query
SELECT *
FROM emp_view;

-- Replace
CREATE OR REPLACE VIEW emp_view AS
SELECT employee_id, first_name, salary, department_id
FROM employees;

-- Read-only
CREATE VIEW emp_readonly AS
SELECT employee_id, first_name, salary
FROM employees
WITH READ ONLY;

-- Check option
CREATE VIEW high_salary_emp AS
SELECT employee_id, first_name, salary
FROM employees
WHERE salary >= 100000
WITH CHECK OPTION;

-- Compile
ALTER VIEW emp_view COMPILE;

-- Drop
DROP VIEW emp_view;

One-line interview answer

An Oracle view is a named, stored SQL query that presents data from one or more underlying objects as a virtual table, primarily used for abstraction, security, and simplifying complex queries.

Ultimate memory trick

VIEW
↓
Stores query, not normally the result
↓
Acts like a virtual table
↓
Can hide complexity / columns
↓
May be updatable depending on definition

And remember:

VIEW              → virtual result
MATERIALIZED VIEW  → stored result
TABLE              → stored base data