Your “having” clause works fine, but keep in mind that by doing it that way, you’re asking MySQL to read every row in “people”, evaluating at least one concat_ws() (and it probably evaluates the other immediately too), and then apply the filter once it’s done with that whole operation.
In my experience, that’s the kind of thing that often leads to performance problems under load, due to contention for access to the table (does MySQL still only do table-level locking? I’ve been working with a different RDMS lately..), and heavier use of temp if your people table is at all large.
So anyway, if it’s possible in your situation, you might want to use a where clause like this instead:
where first_name = ‘John’ and last_name = ‘Doe’
That way MySQL can filter first (using an index, if you’ve got one over first_name & last_name), then grab the other column values and evaluate the concat_ws() calls.
If the “John Doe” part is coming from user input – like, you’re allowing users to filter the list of people based on a single input field – and assuming you’re building your SQL in program code, then you could split their input into search terms on any whitespace, trim non-alpha characters from each term, and build a where clause. You’d end up with something like so:
where (first_name = ‘John’ or last_name = ‘John’)
and (first_name = ‘Doe’ or last_name = ‘Doe’)
That changes the semantics of the query subtly, in that a user search for “Doe, John” would produce the same results as one for “John Doe”, but that could be considered a feature. :)