Recent chats
ASKGEEZ Q&A GUIDETechnology & devices

How can I include or exclude several exact values with an IN filter?

Quick answer

Use IN to select rows whose value matches any item in a list, such as WHERE status IN ('new', 'paid'). Use NOT IN to select rows matching none of those items. In SQLite, a row with a NULL status passes neither filter in a WHERE clause. If you want NULL-status rows included with an exclusion filter, add OR status IS NULL. [S1]

LET’S WORK THROUGH IT

The question, the details, the next step.

Question

I need to filter orders by several exact status values. How do I do that without a chain of OR conditions?

Geez

Use IN with a comma-separated list in parentheses. It selects a row when the compared value matches any item in that list. For example, imagine this invented SQLite table:

order_idstatus
101new
102paid
103shipped
104cancelled
105NULL

To keep new and paid orders, write:

SELECT order_id, status
FROM orders
WHERE status IN ('new', 'paid');

From the example rows, the result is (101, new) and (102, paid). SQLite’s IN operator compares the left-hand expression with the listed values. [S1]

Follow-up question

What if I want everything except new and paid? Does NOT IN include the NULL-status row?

Geez

Use NOT IN to select rows whose status matches neither listed value:

SELECT order_id, status
FROM orders
WHERE status NOT IN ('new', 'paid');

For the invented rows, the result is (103, shipped) and (104, cancelled). It does not include (105, NULL): in SQLite, when the status is NULL, the NOT IN comparison evaluates to NULL rather than true, so the row does not pass the WHERE condition. The same NULL status is not selected by the IN filter either. [S1]

If you want to exclude new and paid but keep rows with a missing status, make that explicit:

SELECT order_id, status
FROM orders
WHERE status NOT IN ('new', 'paid') OR status IS NULL;

That returns shipped, cancelled, and the NULL-status row in this example.

Follow-up question

Is there anything to watch for if I build the list dynamically or add more values?

Geez

Check the values that end up in the list, especially if it could contain NULL. In SQLite, a NULL in the right-hand list can make a nonmatching comparison evaluate to NULL. For example, if the list is ('new', 'paid', NULL), a status that matches neither named value may not pass a NOT IN condition. [S1]

The meaning of NULL in a list is separate from whether a row’s status is NULL. Decide what you want those cases to do, and make sure the list contains only the values intended for the filter. The behavior described here is for SQLite; check the documentation for the database you use if you are using a different system.

Follow-up question

Can you give me a quick way to choose the filter and check the result?

Geez

Use this rule of thumb:

  1. Choose IN when the listed values are the ones you want to keep.
  2. Choose NOT IN when the listed values are the ones you want to exclude.
  3. Decide separately whether rows with a NULL status should be included. For the SQLite exclusion example, add OR status IS NULL when they should be kept.
  4. Check that the list does not contain an unintended NULL.

For the invented orders, IN ('new', 'paid') returns orders 101 and 102. NOT IN ('new', 'paid') returns 103 and 104; adding OR status IS NULL also returns 105. [S1]

A practical checklist

  • Use IN for values to keep and NOT IN for values to exclude.

  • Check the list contains the values you intend to compare.

  • Decide explicitly whether rows with a NULL column value should be included.

  • Check a dynamically assembled list for an unintended NULL.

A few more useful answers

Does IN require a row to match every listed value?

No. It matches a row when the compared value equals any item in the list. [S1]

Will NOT IN include a row whose status is NULL?

Not in SQLite: the comparison evaluates to NULL rather than true, so the row does not pass WHERE. Add OR status IS NULL if those rows should be included.

What if the NOT IN list contains NULL?

In SQLite, a NULL in the list can make a nonmatching comparison evaluate to NULL, so it may not pass WHERE. [S1]

Sources

References used for this guide.

  1. [S1] SQLite SQL Language Expressions: IN and NOT IN
    sqlite.org · Checked

YOUR QUESTION. YOUR DETAILS.

Let’s work through your situation.

Get a tailored answer or help with your next task. Starts at $1, with a quote before you pay.

Ask your own question
← Back to Geez at Work