I’m trying get a list of all users that do not have ticked a specific custom user field. I managed to get a list of those who have ticked it, but I can’t seem to do the inverse:
SELECT cf.user_id
FROM user_custom_fields cf
WHERE cf.name like 'user_field_5' AND
cf.value = 'true'
For example, cf.value = 'false' gives me an empty list, and so does cf.value = '' and also cf.value = 'null'.
BTW, I found it confusing that the datatype of a confirmation type user field is not boolean but text. I figure it’s to keep the user field table simple with just one data type?
This is because a row is only added to the user_custom_fields table after a user has changed the value. So what you want to do is
Go through the users table
For each user, see if there’s a user_custom_fields row for user_field_5
If so, check whether it’s true, otherwise assume it’s false
In my testing, ticking a boolean saves as true in the database, while unticking saves as NULL
So I think the SQL you want is
SELECT u.id as user_id, cf.value
FROM users u
LEFT JOIN user_custom_fields cf
ON (cf.user_id = u.id and cf.name like 'user_field_5')
WHERE cf.value IS DISTINCT FROM 'true'
Note that IS DISTINCT FROM is needed rather than !=, because it can deal with one of the values being NULL.