Oracle SQL Faq
Oracle SQL Faq
Oracle SQL Faq
$Date: 03-Oct-2003 $
$Revision: 1.91 $
$Author: Frank Naudé $
Topics
What is SQL and where does it come from?
What are the difference between DDL, DML and DCL commands?
How does one escape characters when building SQL queries?
How does one eliminate duplicate rows from a table?
How does one generate primary key values for a table?
How does one get the time difference between two date columns?
How does one add a day/hour/minute/second to a date value?
How does one count different data values in a column?
How does one count/sum RANGES of data values in a column?
Can one retrieve only the Nth row from a table?
Can one retrieve only rows X to Y from a table?
How does one select EVERY Nth row from a table?
How does one select the TOP N rows from a table?
How does one code a tree-structured query?
How does one code a matrix report in SQL?
How does one implement IF-THEN-ELSE in a select statement?
How can one dump/ examine the exact content of a database column?
Can one drop a column from a table?
Can one rename a column in a table?
How can I change my Oracle password?
How does one find the next value of a sequence?
Workaround for snapshots on tables with LONG columns
Where can one get more info about SQL?
Back to Oracle FAQ Index
In common usage SQL also encompasses DML (Data Manipulation Language), for INSERTs,
UPDATEs, DELETEs and DDL (Data Definition Language), used for creating and modifying
tables and other database structures.
The development of SQL is governed by standards. A major revision to the SQL standard was
completed in 1992, called SQL2. SQL3 support object extensions and are (partially?)
implemented in Oracle8 and 9.
Method 1:
Method 2:
Note: One can eliminate N^2 unnecessary operations by creating an index on the joined fields in
the inner loop (no need to loop through the entire table on each pass by a record). This will
speed-up the deletion process.
Note 2: If you are comparing NOT-NULL columns, use the NVL function. Remember that NULL is
not equal to NULL. This should not be a problem as all key columns should be NOT NULL by
definition.
How does one get the time difference between two date
columns?
Look at this example query:
select floor(((date1-date2)*24*60*60)/3600)
floor((((date1-date2)*24*60*60) -
floor(((date1-date2)*24*60*60)/3600)*3600)/60)
round((((date1-date2)*24*60*60) -
floor(((date1-date2)*24*60*60)/3600)*3600 -
(floor((((date1-date2)*24*60*60) -
floor(((date1-date2)*24*60*60)/3600)*3600)/60)*60)))
from ...
If you don't want to go through the floor and ceiling math, try this method (contributed by Erik
Wile):
select to_char(to_date('00:00:00','HH24:MI:SS') +
from ...
Note that this query only uses the time portion of the date and ignores the date itself. It will thus
never return a value bigger than 23:59:59.
Back to top of file
NOW NOW_PLUS_30_SECS
-------------------- --------------------
from my_table
group by my_table_column;
count(decode(sex,'M',1,'F',1)) TOTAL
from my_emp_table
group by dept;
select f2,
from my_table
group by f2;
1, 0.1,
2, 0.2,
3, 0.31) "Tax rate"
from my_table;
SELECT * FROM t1 a
FROM t1 b
SELECT * FROM (
WHERE RN = 100;
Note: In this first query we select one more than the required row number, then we select the
required one. Its far better than using a MINUS operation.
SELECT f1 FROM t1
WHERE rowid = (
MINUS
Alternatively...
Please note, there is no explicit row order in a relational database. However, this query is quite
fun and may even help in the odd situation.
Back to top of file
SELECT * FROM (
Note: the 101 is just one greater than the maximum row of the required rows (means x= 90,
y=100, so the inner values is y+1).
Another solution is to use the MINUS operation. For example, to display rows 5 to 7, construct a
query like this:
SELECT *
FROM tableX
WHERE rowid in (
MINUS
Please note, there is no explicit row order in a relational database. However, this query is quite
fun and may even help in the odd situation.
Back to top of file
SELECT *
FROM emp
FROM emp);
SELECT *
FROM emp
) temp
WHERE MOD(temp.ROWNUM,4) = 0;
SELECT rownum, f1
FROM t1
Please note, there is no explicit row order in a relational database. However, these queries are
quite fun and may even help in the odd situation.
Back to top of file
SELECT *
SELECT *
FROM my_table a
FROM my_table b
The SCOTT/TIGER database schema contains a table EMP with a self-referencing relation
(EMPNO and MGR columns). This table is perfect for tesing and demonstrating tree-structured
queries as the MGR column contains the employee number of the "current" employee's boss.
The LEVEL pseudo-column is an indication of how deep in the tree one is. Oracle can handle
queries with a depth of up to 255 levels. Look at this example:
from EMP
One can produce an indented report by using the level number to substring or lpad() a series of
spaces, and concatenate that to the string. Look at this example:
One uses the "start with" clause to specify the start of the tree. More than one record can match
the starting condition. One disadvantage of having a "connect by prior" clause is that you cannot
perform a join to other tables. The "connect by prior" clause is rarely implemented in the other
database offerings. Trying to do this programmatically is difficult as one has to do the top level
query first, then, for each of the records open a cursor to look for child nodes.
One way of working around this is to use PL/SQL, open the driving cursor with the "connect by
prior" statement, and the select matching records from other tables on a row-by-row basis,
inserting the results into a temporary table for later retrieval.
SELECT *
sum(decode(deptno,10,sal)) DEPT10,
sum(decode(deptno,20,sal)) DEPT20,
sum(decode(deptno,30,sal)) DEPT30,
sum(decode(deptno,40,sal)) DEPT40
FROM scott.emp
GROUP BY job)
ORDER BY 1;
ANALYST 6000
PRESIDENT 5000
SALESMAN 5600
Some examples:
from employees;
0, 'a = b',
Note: The decode function is not ANSI SQL and is rarely implemented in other RDBMS offerings.
It is one of the good things about Oracle, but use it sparingly if portability is required.
From Oracle 8i one can also use CASE statements in SQL. Look at this example:
SELECT ename, CASE WHEN sal>1000 THEN 'Over paid' ELSE 'Under paid'
END
FROM emp;
SELECT DUMP(col1)
FROM tab1
DUMP(COL1)
-------------------------------------
For this example the type is 96, indicating CHAR, and the last byte in the column is 32, which is
the ASCII code for a space. This tells us that this column is blank-padded.
Back to top of file
Other workarounds:
rename t1 to t1_base;
create view t1 <column list with new name> as select * from t1_base;
create table t2 <column list with new name> as select * from t1;
rename t2 to t1;
From Oracle8 you can just type "password" from SQL*Plus, or if you need to change another
user's password, type "password user_name".
You can use the above technique to prevent sequence number loss before a SHUTDOWN
ABORT, or any other operation that would cause gaps in sequence values.
COPY TO SCOTT/TIGER@REMOTE -
FROM IMAGES;
Note: If you run Oracle8, convert your LONGs to LOBs, as it can be replicated.
Back to top of file