Thanks, guys. You sure are smarter than me.
I'm a professional. I've done advance studying in logical data modeling... what do I know? I'm a geezer. I'm an IT manager in the telecommunications industry. I hire consultants. I present them with examples like the ones above and ask opinions. If they know and understand best practices, I may hire them. If they don't know or understand best practice, I find someone else.
Piranha you're right insofar as you go. My LEFT JOIN example might be thought of as an adhoc query. Such queries are fairly common as one-off management requests in most industry environments. In a production environment, one would be more rigorous, of course.
Laserlight: you ask: what does 0 and 1 mean? In most data processing that I've encountered 0 and 1 mean false and true respectively. If you wanted to assign 'Yes' or 'No' to as values, you could do so. In my response to Piranha's example, a reasonable person could look at an 'Available' column and discern that 'available=0' meant not available. But when looking at 'price IS NULL' what is the reasonable person to discern? In this case NULL carries a meaning other than 'price'. You'd need to explain that NULL means not yet set or not yet available. Such information is NOT the price. Such information is some sort of status.
If you think my advice is half-assed, that may be because you have not yet dealt with databases built with stupid ass design. Which is the exact sort of problem that started this thread.
In the problem that started this thread: WHY is this status field being populated with strings? Who came up with the idea of using strings? Someone who didn't know better.
Better design would be to populate with integers...these to relate to text either by library defiinition or in some related 'status' table: 0 = '', 1='Email', 2='Call', etc. So the simple query:
SELECT * FROM table WHERE status IN (1,3,4)
Which is pretty easy to understand, edit, etc,
and no need for LIKE, regular expressions, etc. A nice thing about this sort of good design is that statuses become effectively unlimited. Also long and helpful status meanings can be stored in a related table (status 16='Customer is a complete airhead, call only at your own risk')
"Clever" usages (like 'NULL means price not yet assigned') are what leads to surprises. In the industry, people don't like surprises.
As to your 'taking a feature and calling it a bug', please re-read the comment I made: such queries 'behave differently than might be expected'. Maybe you are already smart enough to know how your query will return data. Maybe you'll remember that price can be null, and you will include an asterisk and footnote about what this means when reporting your results.
Let me give you a better adhoc query example:
SELECT id, IF(price>10,'expensive', 'cheap') FROM product
Do you know by looking wheter this query will or will not return a list of all product ids?