Filtering rows is how SQL earns its keep. A basic predicate compares two expressions with a comparison operator and yields TRUE, FALSE, or UNKNOWN. DB2 for z/OS supports the six standard operators (=, <>, <, >, <=, >=) plus older spellings such as != that you should recognise but not copy. This page covers each operator, null behaviour, and binary comparisons for byte strings.
A basic predicate has the shape expression operator expression. The operands must be comparable (compatible types under comparison rules). If either operand is null, the result is unknown. Otherwise the result is true or false. WHERE, HAVING, and ON keep rows only when the search condition is true—unknown is discarded just like false. That is why three-valued logic belongs in the same lesson as =.
| Operator | True when |
|---|---|
| = | Equal |
| <> | Not equal (standard spelling) |
| != ^= ¬= | Not equal (legacy spellings—avoid in new SQL) |
| < | Less than |
| > | Greater than |
| <= | Less than or equal (legacy: ^> !> ¬> ) |
| >= | Greater than or equal (legacy: ^< !< ¬< ) |
The six operators can be rewritten using just = and < if you like algebra: x <> y is NOT (x = y); x > y is y < x; x <= y is x < y OR x = y; x >= y is y < x OR x = y. Db2 still has first-class tokens for all six.
123456SELECT EMPNO, LASTNAME, SALARY FROM HR.EMPLOYEE WHERE WORKDEPT = 'A00' AND SALARY < 20000 AND PRSTAFF <> :VAR1 AND SALARY > (SELECT AVG(SALARY) FROM HR.EMPLOYEE);
= is true when the two values are equal under the comparison rules for their types. Numbers compare numerically (1.00 equals 1 for DECIMAL vs INTEGER after conversion). Strings compare according to length, padding, and CCSID conversion. Datetime values compare chronologically. Distinct types compare if they are the same distinct type (and not LOB-based).
Character comparison is not always “what an English speaker means by alphabetical.” EBCDIC puts letters and digits in a different code-point order than ASCII. Always know the CCSID before you sort or range-scan character keys.
123WHERE EMPNO = '000010' WHERE SALARY = 50000 WHERE HIREDATE = CURRENT DATE
Never write WHERE COL = NULL. That predicate is unknown for every row. Use IS NULL. The same trap exists for host variables: if the indicator says null, the = comparison does not become “equal to the null in the column”; it becomes unknown.
<> is the standard not-equal operator: true when the values are not equal and both are not null. IBM also accepts product-specific forms !=, ^=, and in some code pages ¬=. Those extra forms exist so old applications keep compiling. They are not recommended for new SQL.
12WHERE WORKDEPT <> 'A00' -- Avoid in new code: WHERE WORKDEPT != 'A00'
NOT (x = y) is logically the same as x <> y when neither is null. When nulls are present, NOT of unknown is still unknown, so NOT (COL = 'A') does not pick up the null COL rows either. Use IS NOT NULL if you must include or exclude missing values explicitly.
< is true when the left operand is strictly less than the right. > is true when the left is strictly greater. Equality is false for both. For numbers this is ordinary magnitude. For DATE/TIME/TIMESTAMP it is earlier / later. For strings it is the comparison sequence after any conversions—not a linguistic dictionary order unless your collating setup makes it so.
123WHERE SALARY < 20000 WHERE HIREDATE > DATE('2015-01-01') WHERE LASTNAME < 'M'
Range predicates often combine them: SALARY > 20000 AND SALARY < 40000. BETWEEN is a related predicate (covered with other predicates) that includes the endpoints; < and > do not.
<= is true when the left operand is less than or equal to the right. >= is true when it is greater than or equal. Inclusive ranges use these (or BETWEEN).
Legacy spellings map onto these operators and are easy to misread:
The ¬ character is only documented for certain code pages (historically 437, 819, and 850). On z/OS EBCDIC source, ¬ can appear in old COBOL SQL. Do not introduce it in new text; type <= and >=.
123WHERE SALARY >= 20000 WHERE SALARY <= 40000 WHERE (YEARVAL, MONTHVAL) >= (2009, 10)
Row-value comparisons like (YEARVAL, MONTHVAL) >= (2009, 10) compare left-to-right like a sort key: year first, then month. Support and exact rules follow the SQL Reference for your function level; the idea is “tuple order,” not independent ANDs of each column.
Binary comparisons means comparing binary string values (BINARY, VARBINARY, BLOB) byte for byte, and more loosely the idea that Db2 string comparison is code-point / binary after conversion rather than a linguistic collator like some Unicode-aware products.
123WHERE BIN_COL = BX'00FF' WHERE BIN_COL <> BX'0000' WHERE BIN_COL >= BX'80'
For character columns, “binary comparison” talk usually means: no case folding, no ignoring spaces beyond the type’s pad rules, order by CCSID code points. If you need case-insensitive search, use UPPER/LOWER (and accept the index implications) or a generated column designed for that.
= and friends build predicates. AND, OR, and NOT combine those truth values. Mixing them without parentheses is a readability bug even when precedence is defined. Put parentheses around OR groups: (A = 1 OR B = 2) AND C = 3.
A comparison is asking a yes/no question: “are these two stickers the same?” (=), “are they different?” (<>), “is this pile smaller?” (<), “bigger?” (>), or “smaller or the same?” (<=). If one sticker is missing (NULL), the answer is not yes and not no—it is “I cannot tell,” and the row does not get to stay in the WHERE club. != is a slang way some old books wrote “different”; the polite spelling is <>. Binary comparison is lining up toy bricks and checking whether each brick matches, without reading them as words.
The standard six are = (equal), <> (not equal), < (less than), > (greater than), <= (less than or equal), and >= (greater than or equal). Product-specific spellings !=, ^=, ¬=, and related forms exist for compatibility with old SQL and should not be used in new statements.
Equality with null is unknown, and WHERE discards rows that are not true. Test absence with IS NULL (and IS NOT NULL), not with = NULL.
In Db2 they are treated as the same not-equal comparison when != is accepted, but != is a product-specific form. Write <> in new SQL so the statement is standard and portable.
BINARY, VARBINARY, and BLOB values compare as bytes. Character FOR BIT DATA is still in the character family for many rules. Do not compare a BX literal to an X literal and expect them to be the same type.
Simple column-to-literal comparisons (=, <, >, >=, <=) are the usual index-friendly predicates when the column is the left side and not wrapped in a function. Expressions on the column can prevent matching on that index.
1. What does a basic comparison return if either operand is NULL?
2. Which not-equal operator should you write in new SQL?
3. Is 5 >= 5 true?
4. How are character strings compared in Db2?
5. Can you compare two different distinct types without a cast?