The CREATE TABLE statement allows you to create and define a table.
The basic syntax for a CREATE TABLE statement is:
    CREATE TABLE table_name
    ( column1 datatype null/not null,
      column2 datatype PRIMARY KEY,
      column3 datatype PRIMARY KEY,
      …
    );

Each column must have a datatype. The column should either be defined as “null” or “not null” and if this value is left blank, the database assumes “null” as the default.
Example 1:
CREATE TABLE XX_PO_HEADERS_ALL
(
PO_ID         NUMBER(12) PRIMARY KEY,
PO_NUMBER     NUMBER(12),
SUPPLIER_NAME VARCHAR2(12) NOT NULL,
SUPPLIER_SITE VARCHAR2(12),
SHIP_TO       VARCHAR2(12),
BILL_TO       VARCHAR2(12)
)
Example 2:
CREATE TABLE XX_PO_LINES_ALL
(
PO_ID         NUMBER(12),
LINE_NUMBER   NUMBER(12),
ITEM_NAME     VARCHAR2(12),
QUANTITY      NUMBER(12),
ITEM_PRICE    NUMBER(12),
ITEM_TAX      NUMBER(12),
LINE_PRICE    NUMBER(12),
ORDER_DATE    DATE,
NEED_DATE     VARCHAR2(12),
BILL_TO       VARCHAR2(12)
)

Column Default Values

You can define tables to populate columns with default values as well using the default clause in a create table command. This clause is included as part of the column definition to tell Oracle what the default value for that column should be. When a row is added to the table and no value is defined for the column in the row being added, Oracle populates the column value for that row using the default value for the column. The following code block illustrates this point:
SQL> create table display
  2  (col1 varchar2(10),
  3   col2 number default 0);

Table created.
CREATE a table from another table
You can also create a table from an existing table by copying the existing table’s columns.
The basic syntax is:
CREATE TABLE table_name
  AS (SELECT * FROM old_table);

Example1:
CREATE TABLE XX_PO_HEADERS_ALL_COPY
AS (Select * From XX_PO_HEADERS_ALL)

The above statement ‘ll create a new table that is just an exact copy of XX_PO_HEADERS_ALL.
Example 2:  Copying selected columns from another table
The basic syntax is:
    CREATE TABLE new_table
      AS (SELECT column_1, column2, … column_n FROM old_table);

Example 3: Copying selected columns from multiple tables
The basic syntax is:
    CREATE TABLE new_table
      AS (SELECT column_1, column2, … column_n
              FROM old_table_1, old_table_2, … old_table_n);

It is important to note that when creating a table in this way, the new table will be populated with the records from the existing table (based on the SELECT Statement). If you want to create a blank table then use a condition which is always false in the where clause of the select statement.
Creating Temporary Tables
Most of the time, when you create a table in Oracle, the records that eventually populate that table will live inside your database forever (or at least until someone removes them). However, there might be situations where you want records in a table to live inside the database only for a short while. In this case, you can create temporary tables in Oracle, where the data placed into the tables persists for only the duration of the user session, or for the length of your current transaction.
A temporary table is created using the create global temporary table command. Why does a temporary table have to be global? So that the temporary table’s definition can be made available to every user on the system. However, the contents of a temporary table are visible only to the user session that added information to the temporary table, even though everyone can see the definition. Temporary tables are a relatively new feature in Oracle, and Oracle hasn’t had enough time yet to implement “local” temporary tables (that is, temporary tables that are only available to the user who owns them). Look for this functionality in later database releases. The appropriate create global temporary table command is shown in the following code block:

Create global temporary table XXX_PO_HEADERS_ALL as
Select *
From PO_HEADERS_ALL
Where 10=11

The purpose of writing the where clause is to make the temporary table blank. If we dont put the where clause the temporary table would contain all the rows of XXX_PO_HEADERS_ALL
Data definition language (DDL) refers to the subgroup of SQL statements that create, alter, or drop database objects.
This sub-category of SQL statements is of particular interest to database architects or database administrators who must define an original database design and who must respond to requirements and extend a database design. It is also of interest to database application developers, because there are times when the easiest way to meet an application requirement is to extend an existing database object definition.
In general DDL statements begin with one of the following keywords: CREATE, ALTER, or DROP. Examples of DDL statements for creating database objects include: CREATE TABLE, CREATE TRIGGER, CREATE PROCEDURE, and CREATE SEQUENCE. These statements generally contain multiple clauses used to define the characteristics and behavior of the database object. Examples of DDL statements for altering database objects include: ALTER TABLE, and ALTER PROCEDURE. These statements generally are used to alter a characteristic of a database object.
DDL statements can be executed from a variety of interactive and application interfaces although they are most commonly executed in scripts or from integrated development environments that support database and database object design.
Describing Tables
The best way to think of a table for most Oracle beginners is to envision a spreadsheet containing several records of data. Across the top, try to see a horizontal list of column names that label the values in these columns. Each record listed across the table is called a row. In SQL*Plus, the command describe enables you to obtain a basic listing of characteristics about the table.
SQL> DESCRIBE po_headers_all
Name                       Type           Nullable Default                                                                                                Comments
————————– ————– ——– —————————
PO_HEADER_ID               NUMBER                                                                                                                                 
AGENT_ID                   NUMBER(9)                                                                                                                              
TYPE_LOOKUP_CODE           VARCHAR2(25)                                                                                                                           
LAST_UPDATE_DATE           DATE                                                                                                                                   
LAST_UPDATED_BY            NUMBER                                                                                                                                 
SEGMENT1                   VARCHAR2(20)   R2(1)
Commenting Objects
You can also add comments to a table or column using the comment command. This is useful especially for large databases where you want others to understand some specific bits of information about a table, such as the type of information stored in the table. An example of using this command to add comments to a table appears in the following block:
SQL> comment on table employee is
  2  ‘This is a table containing employees’;
Comment created.

You can see how to use the comment command for adding comments on table columns in the following code block:
SQL> comment on column employee.empid is
  2  ‘unique text identifier for employees’;
Comment created.

Tip    
Comment information on tables is stored in an object called USER_TAB_COMMENTS, whereas comment information for columns is stored in a different database object, called USER_COL_COMMENTS. These objects are part of the Oracle data dictionary. You’ll find out more about the Oracle data dictionary later in the book.
You can also write subqueries that appear in your from clause. Writing subqueries in the from clause of the main query can be a handy way to collect an intermediate set of data that the main query treats as a table for its own query-access purposes. This subquery in the from clause of your main query is called an inline view. You must enclose the query text for the inline view in parentheses and also give a label for the inline view so that columns in it can be referenced later. The subquery can be a select statement that utilizes joins, the group by clause, or the order by clause
Select a.PO_HEADER_ID, a.Segment1, b.unit_price, b.Quantity
From PO_HEADERS_ALL a,
(
Select unit_price, Quantity, po_header_id
From PO_LINES_ALL
) b
Where a.PO_HEADER_ID=b.PO_HEADER_ID
Inline Views and Top-N QueriesTop-N queries use inline views and are handy for displaying a short list of table data, based on “greatest” or “least” criteria. For example, let’s say that profits for our company were exceptionally strong this year, and we want a list of the three lowest-paid employees in our company so that we could give them a raise. A top-N query would be useful for this purpose. Take a look at a top-N query that satisfies this business scenario:
SQL> select ename, job, sal, rownum
  2  from (select ename, job, sal from emp
  3        order by sal)
  4  where rownum <=3;
ENAME      JOB             SAL     ROWNUM
———-     ———         ———   ———
SMITH      CLERK           800         1
JAMES      CLERK           950         2
ADAMS      CLERK          1100       3
You need to know two important things about top-N queries for OCP. The first is their use of the inline view to list all data in the table in sorted order. The second is their use of ROWNUM—a virtual column identifying the row number in the table—to determine the top number of rows to return as output. Conversely, if we have to cut salaries based on poor company performance and want to obtain a listing of the highest-paid employees, whose salaries will be cut, we would reverse the sort order inside the inline view, as shown here:
SQL> select ename, job, sal, rownum
  2  from (select ename, job, sal from emp
  3        order by sal desc)
  4  where rownum <=3;
ENAME      JOB             SAL    ROWNUM
———- ——— ——— ———
KING       PRESIDENT      5000         1
SCOTT      ANALYST        3000         2
FORD       ANALYST        3000         3
Notice that in all the prior examples, regardless of whether one row or multiple rows were returned from the sub query, each of those rows contained only one column’s worth of data to compare at the main query level. The main query can be set up to handle multiple columns in each row returned, too. To evaluate how to use multiple-column sub queries, let’s consider an example
Select *
From PO_LINES_ALL
Where (PO_HEADER_ID, PO_LINE_ID) IN
(
Select PO_HEADER_ID, PO_LINE_ID
From PO_LINE_LOCATIONS_ALL
WHERE QUANTITY_RECEIVED < QUANTITY/2
AND CLOSED_CODE <> ‘CLOSED FOR RECEIVING’
)
The benefit of writing query in above format is that separating the requirements in tables. From PO_LINE_LOCATIONS_ALL we are only taking those data which are relevant for our purpose and our end aim is to view the PO_LINEA_ALL entries corresponding to some required conditions satisfied by entries in PO_LINE_LOCATIONS_ALL.

A multi row subquery   returns one or more rows.  Since it returns multiple values, the query must use the set comparison operators (IN,ALL,ANY).   If you use a multi row subquery with the equals comparison operators, the database will return an error if more than one row is returned.

Exampe:
select last_name from employees where manager_id in
(select employee_id from employees where department_id in
(select department_id from departments where location_id in
(select location_id from locations where country_id=’UK’)));

with
You can improve the performance of this query by having Oracle9i execute the subquery only once, then simply letting Oracle9i reference it at the appropriate points in the main query. The following code block gives a better logical idea of the work Oracle must perform to give you the result. In it, the bold text represents the common parts of the subquery that are performed only once, and the places where the subquery is referenced:

SQL> with summary as
  2  (select dname, sum(sal) as dept_total
  3   from emp, dept
  4   where emp.deptno = dept.deptno
  5   group by dname)
  6  select dname, dept_total
  7  from summary
  8  where dept_total >
  9  (select sum(dept_total) * 1/3
 10   from summary)
 11  order by dept_total desc;
DNAME                DEPT_TOTAL
——————– ———-
RESEARCH                  10875