This article describes five(5) misconceptions about the behaviour of the popular Oracle database system.
1-Logical conditions on Null values
2-Zero-length character strings
3-Using aliases in Where and Order by clauses
4-Using * with column names in queries
5-Using rownum
2. Question #1 for an Oracle SQL expert
Which of the queries below contain the rows with Null Salary?
SELECT * FROM Persons WHERE SALARY > 1000
SELECT * FROM Persons WHERE SALARY <= 1000
3. Answer
In fact, the conditions
both implicitly assume that SALARY is not NULL.
SALARY > 1000 and SALARY <= 1000
None of them
4. All logical operators are FALSE when one operand is NULL
NULL = 1
NULL != 1
NULL > 1
NULL = "ABC"
NULL != "ABC"
NULL LIKE "Steve%"
NULL NOT LIKE "Steve%"
NULL = NULL
All the below examples return FALSE
5. How do we get the rows where SALARY is NULL?
We use the operator IS NULL
SELECT * FROM Persons WHERE SALARY IS NULL
6. How to check whether a value is Null or Not?
Recall from earlier, the below conditions are always FALSE
โข COL = NULL
โข COL != NULL
Use the below operators instead
โข IS NULL
โข IS NOT NULL
7. Question #2 for an Oracle SQL expert
Which condition detects a zero-length character field?
WHERE COL = โโ
WHERE Length(COL) = 0
9. Explanations
โข In Oracle character fields cannot be of zero length.
โข Oracle substitutes NULL to a โโ literal in Queries
โข When we insert a โโ in a cell , NULL gets inserted
โข The condition X = โโ is interpreted as X = NULL -> a condition that
is always false.
10. โข So, to test if a Col is empty, we test if itโs null:
โข Length(COL) = 0 does not work, since Length(NULL) is NULL.
โข The correct condition based on length is:
โข So, itโs more concise to use the first condition.
WHERE COL IS NULL
WHERE Length(COL) IS NULL
11. Question#3 for an Oracle SQL expert
What does the queries below do?
SELECT NAME, age, weight / ( height * height )
AS BMI FROM persons ORDER BY BMI
SELECT NAME, age, weight / ( height * height )
AS BMI FROM persons WHERE BMI > 25
12. Answer
They both raise errors
Oracle does not accept using a column alias in Where or Order by
clauses.
13. Solution 1
Repeat the definitions of the aliases when needed
SELECT NAME, age, weight / ( height * height ) AS BMI FROM
persons ORDER BY weight / ( height * height)
SELECT NAME, age, weight / ( height * height ) AS BMI FROM
persons WHERE weight / ( height * height) > 25
Cons:
โข Too much redundancy.
โข Query is too long.
โข Every time we change one alias, we must modify it definition in several
locations.
14. Solution 2
This method is generic and works in all cases
SELECT * FROM
(SELECT NAME, age, weight / (height * height) AS BMI FROM PERSONS)
WHERE BMI > 25
SELECT * FROM
(SELECT NAME, age, weight / (height * height) AS BMI FROM PERSONS)
ORDER BY BMI
The part between parentheses acts as a new temporary table, that now has a column
named after each alias. Now, we can use the aliases in the WHERE and ORDER BY
expressions.
15. Question #4 for an Oracle SQL expert
What does the following requests return?
SELECT ColX, * from MYTABLE
SELECT ColX, * , ColZ from MYTABLE
16. Answer
Oracle, only accepts the asterisk when itโs the only thing between the Select and From, as in:
Select * from MYTABLE
If we mix, columns with asterisk, (as in the queries below) Oracle will not
understand the syntax and will raise errors.
Select ColX, * from MYTABLE
Select ColX, *, ColZ from MYTABLE
17. Good news! Oracle will accept the syntax if we simply prefix the
asterisk symbol with the table name (or table alias name), as
shown below:
Select colX, MYTABLE.* from MYTABLE
Select colX, m.* from MYTABLE m
18. Question #5 for an Oracle SQL expert
Which of the below queries gets the top N rows from a table?
Select TOP N * from MYTABLE
Select * from MYTABLE LIMIT 10
19. Answer
โข They both fail.
โข Syntax 1 works on SQL Server
โข Syntax 2 works on MySQL
โข On Oracle, we must use the pseudo-column rownum, that is a virtual
column that represents the line number.
Select * from MYTABLE where ROWNUM <=N
20. โข So, if we want to get the first 3 rows, we can use:
โข Rownum can also be included in the list of fields, allowing us to display the number
of each row:
Select * from MYTABLE where rownum < 4
Select rownum, MYTABLE.* from MYTABLE where rownum < 4
21. Beware of rownum pitfall #1
Remember that filtering is executed before the sorting
will sort the list containing the first 3 students in the table - Not very useful.
The proper way to get the top N rows of a sorted query is to use an inline
view as shown below:
Select Name, Grade from Students where rownum < 4 order by grade
SELECT * FROM
(SELECT Name, Grade FROM Students ORDER BY Grade)
WHERE ROWNUM < 4
22. Beware of rownum pitfall 2
The first row that breaks the condition on rownum will stop the execution
of the query. The below conditions, for example, will yield no results
since they fail on the first row of the table.
ROWNUM > 1
ROWNUM = 3
There is a workaround for this limitation by using an inline view
containg rownum.
Select * from
(Select ROWNUM AS lineNb, mytabe.* from mytable WHERE ROWNUM < 4)
WHERE lineNb = 3