Operators are tokens which are used to perform operations on values (e.g., constants, or identifiers), and return the results of that operation. The significance of each operator is highly dependent on its context.
In addition to the special character symbols defined as operators (see the section called Operator symbols in Chapter 3), there are some SQL keywords which are also considered operators due to their syntactic effect on values in a SQL statement. Throughout this section both these symbols and keywords will be referred to as operators.
![]() | Operator Availability |
|---|---|
For an up to date and complete list of PostgreSQL supported operators, you can always use psql's \do slash command to view a list of available operators. Understand that many of the listed operators are PostgreSQL-specific, and they therefore may not exist in other SQL-capable databases implementations. Operators affecting SQL92 compliant data types are generally fairly standard. |
Each operator has its own associated functionality, and can only operate on specific data types (see the section called Data Types in Chapter 3, for more information on what data types are available). For example, you can use the addition operator (+) to add two integer values together, but you cannot use it to add an integer to a text type. This is an undefined (and therefore ambiguous, and disallowed) use of the operator. As the operator character itself (+, in this case) will still be recognized, you will receive an error if you try to misuse an operator with an explanation similar to that shown in Example 4-37.
Consider the Book Town authors table, which correlates author's names with numeric identifiers.
booktown=# SELECT * FROM authors;
id | last_name | first_name
-------+-----------+------------------
136 | Brown | Margaret W.
1111 | Denham | Ariel
15990 | Bourgeois | Paulette
2031 | Williams | Margary
25041 | Bianco | Margery Williams
1809 | Geisel | Theodor Seuss
16 | Alcott | Louisa May
15 | Poe | Edgar Allen
4156 | King | Stephen
1866 | Herbert | Frank
2001 | Clarke | Anthony C.
1212 | Worsley | John
1644 | Hogarth | Burne
(13 rows)Two identifiers in this table are the columns id, and last_name, which are of type integer (a 4-byte integer) and text, respectively. Since the id column is of type integer, it may be used with a mathematical operator along with another numeric type.
Example 4-36. Correct Operator Usage
booktown=# SELECT (id + 1) AS id_plus_one FROM authors;
id_plus_one
-------------
137
1112
15991
2032
25042
1810
17
16
4157
1867
2002
1213
1645
(13 rows)Notice, however, the result of trying to add incompatible types in Example 4-37.
Table 4-8. Mathematical operators
| Operator | Description | Example | Result |
|---|---|---|---|
| + | Addition | 2+3 | 5 |
| - | Subtraction | 2-3 | -1 |
| * | Multiplication | 2*3 | 6 |
| / | Division (integer division truncates results) | 4/2 | 2 |
| % | Modulo (remainder) | 5 % 4 | 1 |
| ^ | Exponentiation | 2 ^ 3 | 8 |
| |/ | Square root | |/25 | 5 |
| ||/ | Cube root | ||/27 | 3 |
| ! | Factorial | 5! | 120 |
| !! | Factorial (prefix operator) | !!5 | 120 |
| @ | Absolute value | @ -5 | 5 |
| & | Binary AND | 91 & 15 | 11 |
| | | Binary OR | 32 | 3 | 35 |
| # | Binary XOR | 17 # 5 | 20 |
| ~ | Binary NOT | ~1 | -2 |
| << | Binary shift left | 1 << 4 | 16 |
| >> | Binary shift right | 8 >> 2 | 2 |
Arithmetic or mathematical operators can be used in the target list, and in the WHERE clause of a SELECT statement. The statement in Example 4-38 looks at the suggested retail price for each book and triples the price. Note also that the column name is temporarily changed to triple by using the AS keyword.
Example 4-38. Using Mathematical Operators with the AS Clause
booktown=# SELECT p.sugg_price * 3 AS triple, b.title booktown-# FROM publish p, books b booktown-# WHERE p.isbn = b.isbn; triple | title --------+----------------------------- $24.00 | Franklin in the Dark $50.55 | Bartholomew and the Oobleck $13.65 | Goodnight Moon $39.87 | The Velveteen Rabbit $38.97 | Little Women $59.97 | The Cat in the Hat (6 rows)
Comparison operators are used to compare data types like integer or text, but they will always return a boolean value. Table 4-9 shows the available comparison operators.
Table 4-9. Comparison Operators
| Operator | Description |
|---|---|
| < | Less-than |
| > | Greater-than |
| <= | Less-than or equal-to |
| >= | Greater-than or equal-to |
| = | Equivalence, or equal-to |
| <> or != | Inequivalence, or not-equal |
![]() | Not Equal Operator Conventions |
|---|---|
If you specify the not equal to (!=) operator in your query, it is converted to <>. |
This select statement returns all publisher names except for a publisher named ABC Books.
SELECT *
FROM publish
WHERE publ_name <> 'ABC Books';
isbn | publ_name | sugg_price
---------+------------------+------------
2567841 | ODG Books | $12.99
8741205 | Children's Books | $19.99
214872 | Young Readers | $8.00
676883 | Reading Rainbow | $13.29
(4 rows) To see a display of book titles that were published after 1990, use the comparison operators:
Example 4-39. Using Comparison Operators
SELECT title, cpright_date FROM book WHERE cpright_date >= '1990-01-01';
The result displays:
title | cpright_date -----------------------------+-------------- Goodnight Moon | 1991-04-01 Bartholomew and the Oobleck | 1997-02-01 (2 rows)
The comparison operators can be used to look at a table with the book titles, author name, and price of books that cost less than or equal to $13.00. Remember that you are accessing columns from two different tables. This operation requires a join. The command to accomplish this is:
Example 4-40. Using Comparison Operators
SELECT p.sugg_price, b.title, b.author_id FROM publish p, book b WHERE p.isbn = b.isbn AND p.sugg_price <= '13.00';
The output is:
sugg_price | title | author_id
------------+----------------------+-----------
$8.00 | Franklin in the Dark | 142
$4.55 | Goodnight Moon | 136
$12.99 | Little Women | 231
(3 rows)
The BETWEEN keyword provides the ability to compare a value to a range of values. For instance, Example 4-41 shows a SELECT statement which looks for author names between 200 and 250:
The output is:
----------+------------ Williams | Margary Alcott | Luoisa May Williams | Margary Alcott | Luoisa May (4 rows)
You can return the exact same output using the less-than operator (<) in conjunction with the greater-than (>) operator, as you can see in Example 4-42.
Example 4-42. Operator Equivalents to BETWEEN
SELECT lastname, firstname
FROM author
WHERE a_id >= 200 AND a_id <= 250; Using the BETWEEN keyword and a combination of less-than/greater-than operators will output the same result, because when PostgreSQL interprets BETWEEN, it converts it into the less-than/greater-than form. Both forms are valid, and as far as PostgreSQL is concerned, it's really just a matter of user preference.
If a table has NULL values in it, comparison operators can be used to display NULL valued rows:
Example 4-43. Comparisons Using IS NULL
booktown=# SELECT last_name, first_name booktown-# FROM author booktown-# WHERE first_name IS NULL;
Examining Example 4-43 and Example 4-44, you might think that the syntax in the two statements provided are identical.
Example 4-44. Comparisons Equal to NULL
booktown=# SELECT last_name, first_name booktown-# FROM authors booktown-# WHERE first_name = NULL;
![]() | NULL Equivalence |
|---|---|
When comparing a value to NULL in an expression, it is a good idea to be in the habit of using the IS NULL and IS NOT NULL keyword operators. You should avoid using the expression = NULL, because it prompts the parser to look for a value that is literally equal to NULL. If NULL is an unknown value, this kind of comparison is ambiguous. PostgreSQL provides a translation from = NULL to IS NULL, and likewise for the != NULL operation. This is provided only for compatibility with client applications (such as Microsoft Access), but be aware that this functionality may be discontinued in the future. The appropriate choice is to use IS NULL or IS NOT NULL. |
Binary operators also work on bit strings, as shown in the table below.
Table 4-10. Bit String Operators
| Example | Result |
|---|---|
| B'10001' & B'01101' | 00001 |
| B'10001' | B'01101' | 11101 |
| B'10001' # B'01101' | 11110 |
| ~B'10001' | 01110 |
| B'10001' << 3 | 01000 |
| B'10001' >> 2 | 00100 |
![]() | Shifting Bit Strings |
|---|---|
When shifting bit strings, the original length of the string does not change. Also, when using operators such as &, |, and #, the bit strings within the argument must be of equal length. |
Table 4-11 and Table 4-12 illustrate the boolean values returned for AND, OR, and NOT.
Table 4-13. Operator Precedence
| Operator / Element | Associativity | Description |
|---|---|---|
:: | left | PostgreSQL style typecast |
[] | left | array element selection |
. | left | table or column name separator |
- | right | unary minus |
^ | left | exponential |
*/% | left | multiplication, division, and modulo |
+- | left | addition, subtraction |
IS | test for TRUE, FALSE, NULL | |
ISNULL | test for NULL | |
NOT NULL | test for NOT NULL | |
any other | left | all other native and user-defined operators |
IN | set membership | |
BETWEEN | containment | |
OVERLAPS | time interval overlap | |
LIKE ILIKE | string pattern matching | |
<> | less than, greater than | |
= | right | equality, assignment |
NOT | right | logical negation |
AND | left | logical conjunction |
OR | left | logical conjunction |
![]() | User Defined Operators |
|---|---|
Operator precedence rules also apply to user-defined operators that have the same name as the built-in operators mentioned above. For example, if you define dot (.) operator for a custom data type, it has the same precedence as the built in dot (.) operator, no matter what you the defined the operator to do. |
For instance, the BETWEEN keyword is used below to display publisher names whose suggested prices are between $8 and $13.50:
SELECT publ_name FROM publish WHERE sugg_price BETWEEN '8.00' AND '13.50';
The column displayed looks like this:
publ_name ----------------- ODG Books Young Readers Reading Rainbow (3 rows)