If 'name' is a varchar, SELECT * FROM customers WHERE name != 0 returns all the rows where 'name' starts with a number. SELECT * FROM customers WHERE name = 0 returns all the rows where 'name' starts with a letter.
Do you have any entries for 'name' that start with 0 and then letters? If my reading of this is right that will be returned by the second query not the first.
I think what is happening is that MySQL is converting 'name' to a number then doing the comparison. Anything that starts with a number converts to a number other then 0, anything that doesn't start with a number is being converted to 0.
If my reading of the manual is correct, SELECT * FROM customers WHERE !name should return rows where name when converted to a number evaluates to 0 and nothing else. But I could easily be way off. In any case, as a statement it doesn't make much sense. Your applying a logical operator to a character field.
I don't know how this would work in MySQL, but one clever way of doing what you want in MS SQL is SELECT * FROM customer WHERE len(' ' + name) = 1. That works because string + NULL = string and string + empty string = string.
Jay