mysql search across joined fields - mysql

I have customer table with fileds for first name and last name plus other details.
In a form a user can enter a search which I have working but on unique fiels only eg searches for john in any of first name or last name. This all works ok
However I dont know how to search if a user enters john smith which would be a combination of two fields. How can I do this search with my current data structure?
Ive tried adding a field in the select statement using:
Concat_ws (' ', firstname, lastname) as fullname
But I cant use where on this generated field and throws an error
Should I create a new field to contain full name?
Thank you

You don't use aliases in where condition. instead use the complete function
e.g.
where Concat_ws(' ', firstname, lastname) like '%<your search>%'
But, yes, it is good idea to create a new field to optimize performance
And make sure you dont have space after the function name

It depends on which combinations of fields you want. For your example firstname = 'john' AND lastname='smith' would do the job, but its probably not what you need.
The best solution would be to use a fulltext search.

Related

Searching table for fields using multiple possible combinations and wildcards

If in a simple customers table:
customers (first_name varchar(40), last_name varchar(40))
i would like to run a search by customer name, i can do:
[MYSQL...] WHERE (customers.first_name LIKE "%john%" OR customers.last_name LIKE "%john%")
However, if someone uses the search field in the front end to search for a full name, such as john arbuckle, i won't be getting any results.
What is the most effective and easiest way to run this query correctly in MySQL so that it can yield the desired results without losing the wildcard search capability?
The only thing i can think of is to split the string by whitespaces and run multiple logical comparison combinations for each string component. But is that really the way to go? Isn't there perhaps a way to combine fields when comparing their values?

The most efficient sql schema for searching names and lastnames

I'm creating a list of members on my site, and I want to enable them to look for eachother by first name and last name or either one. The catch is that a user can have several names, like names and then nicknames, also a person can have more than one lastnames, their maiden name and then the lastname after marriage.
Once users fillout their names and last names, each user could have several names and last names, for example There could be a person with 3 names and 2 lastnames - names: Eleonora, Ela, El and lastnames: Smith, Brown.
Then if someone looks for Ela Brown, Eleonora Brown, Eleonora Smith or any other combination, they should find this person.
My question, is how should I set this all up in sql (mysql) so tha schema and search is efficient and fast? Didn't want to reinvent a wheel so I turned to pros and asking a question here.
Thanks guys
P.S. I guess the standard solution would be to have a user table, fname table, lname table, userfname table with userid and fnameid and userlname table with userid and lnameid, but I'm not sure if this is the best way to do this and wether or not search would be fast...
Do you need to differentiate between first names and last names?
I would suggest a Users Table having UserID
and also some UsersNames Table having UserID and Name, a one-to-many relationship.
If you need, you could also add a IsLastName bit to the UsersNames table (or just a LastName column, but the bit is better imho)....
But this way you search one table and can easily locate user ID's, plus you don't limit the number of names each user can have.
EDIT:
You could easily take your input string and split it out too. So if somebody put in "John Smith" you could search for both or either name simply by splitting the string and using it in the WHERE clause using either OR or AND depending on your intended functionality.
The last time I did somethig like this I processed each name into a single column in a NAMES table. All names, first/last/middle. A second table hold a link to the person record in the PERSONS table.
So each NAME field get linked to one or more PERSONS record. If I search for "Scott" I would find the name Scott in the NAMES table, find the links in the NAMES_TO_PERSONS(/PEOPLE?) table and then return all the records for that name. ie: Scott Bruns, John Scott, David Scott Smith.
It worked very well with only a small amount of pre processing.
Text searching is what you need - use Lucene. I've used Lucene on several projects and it's truly amazing - not hard to use and ridiculously fast.
If in your data model the users may have multiple but bounded number of name types then the simplest solution would be to create indecies for each column that stores the name type. You would add a field for first name, last name, nickname, maiden name, etc. This model would be more performant than having a one-many names association.
You may also evaluate if there are general search requirements for the rest of the application or if you would like the search to be more flexible. In this case you can look into using a backend indexing process, such as with Lucene or using full text search. Initially, I would try to avoid this if possible, because it certainly complicates the project.

selecting columns based on value in single column

I am complete newbie when it comes to MySQL. I have done some searching around here and elsewhere, but haven't been able to work out something that I imagine is very simple.
I have an email program that imports fields/columns from a MySQL database for bulk emails.
I am wanting to only import information for users that have a particular value in a particular column in a table.
To import all users I would normally use:
SELECT firstname, email FROM users
I have tried amending this to:
SELECT firstname, email FROM users WHERE group = "test"
where group is the name of the column that I am trying to test against, and test is the value I am searching for. I think this might be close, but it brings up an error.
Could someone put me straight?
I think your problem is that group is a keyword in MySQL. You can use
SELECT firstname, email FROM users WHERE `group` = "test"
Use back ticks to quote field names.

Should I name the username field in my user table "name" or "username"?

If I name it username then I would have to write user_username when referring to my field when I can just write user_name if it's named "name". On the other hand, username sounds more appropriate than name.
Can someone help me make a decision?
You should call it username.
The field name (or user_name if you are prefixing all fields with the table name) is ambiguous because it might be their real name, which is usually different from their username.
username, it's more specific and won't get mixed up with proper human names.
Here's a tip: while you're there, it's a good idea to decide on the proper name columns early - first_name and last_name or surname and given_name or whatever. It doesn't really matter, but it's a right pain when tables are inconsistent.
But you can also try nickname.
Another possible option is login

Generating a unique MySQL field based on the contents of other fields

In creating unique custom reference codes (i.e. JOB1293XYZ) for a while I have been generating custom reference/hashes in PHP then checking my database to see if it already exists and if so generating another.
I'm curious if in MySQL it is possible to to generate the contents of a field based on the other fields in that row, i would be a handy shortcut. For Example...
Table: Employees
employeeId
firstName
lastName
jobTitle
DOB
employeeCode
So for employeeCode can I perhaps use a MySQL Custom Function (which I know very little about) to generate the contents of the field. perhaps by taking the first letter of the firstname, first letter of the second name, the str length of the job title and the last two digits of the DOB? This is purely an example.
If this is possible and anyone can point me to any reference material that would be great, have been wading through the heavy MySQL documentation and will continue to do so for the time being.
Thanks in advance!
You could concatenate all of the fields together and do an MD5 on the resulting string.
UPDATE Employees SET md5str=MD5(CONCAT(field1, field2, field3))...
I wouldn't recommend this approach because then the question of what to do if you had a hash collision would be very difficult if not impossible to answer.
The above idea is not mine: I spotted this in the maatkit code.