So I am trying to do this:
SELECT customerID, name, email
FROM Customers
WHERE customerID IN (substrings delineated by spaces of CID string)
Where what I want to happen, is it returns the entries that have a matching customerID.
Unfortunately, the value CID is a string of all the matching CIDs separated by spaces. I've tried to change it to be some sort of list, but no luck on that end. If I could use something like string splitter that would solve my problem, but it doesn't seem to be available in MySQL.
Sorry for the relatively simple question, but an hour of googling has returned no clear answers.
I wonder if you could use the REPLACE function:
SELECT customerID, name, email
FROM Customers
WHERE customerID IN (REPLACE(CID string,' ',','))
https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_replace
One method is like:
SELECT customerID, name, email
FROM Customers
WHERE CONCAT(' ', CID, ' ') LIKE concat('% ', customerID, ' %') ;
I really do advocate that you separate the string. If it is coming from a table, then you probably need a junction/association table.
Try this:
WHERE FIND_IN_SET(CustomerID, REPLACE(spacedList, ' ', ',')) > 0
FIND_IN_SET
You might need to also cast CustomerID to a char, but I would try without the cast first.
Related
Let's assume I have a table which store register user data, the records might have same registered name but different email, like following:
I want to create a front view to manipulate those data but I don't want those same name show repeatedly, can mysql statement query to output result like
this is the result so far I can do but it can't bind same name into one.
select * from `register`
where `fullname` in (
select `fullname` from `register`
group by `fullname` having count(*) > 1
)
One thing you could do is to do a SELECT DISTINCT on the duplicate row, and make use of the GROUP_CONCAT(); function in MYSQL to concatenate your desired values into one row, and GROUP BY fullname to get the order you wanted.
Note that I am also putting the user ids into a grouped row, so that you can track which ids belong to which name.
SELECT
DISTINCT fullname as full_name,
GROUP_CONCAT(id SEPARATOR ', ') as user_ids,
GROUP_CONCAT(email SEPARATOR ', ') as emails
FROM
tbl_register
GROUP BY
tbl_register.fullname
Working SQL Fiddle
This would be the logical way to do it. Hope this helped. :)
More information on the GROUP_CONCAT(); function here: https://dev.mysql.com/doc/refman/8.0/en/group-by-functions.html#function_group-concat
Try this:
SELECT DISTINCT *duplicate_column* FROM *table_name1* WHERE *col_id* IN (SELECT *cols_to_dusplay* FROM *table_name1* GROUP_BY *duplicate_column*
I'm trying to join two columns of the same table but, if there are null values (in my case they are in the second column), I want to take anyway the row that interests me and, rather than putting the null value, I would put ''. The columns that I want to join are Surname and Name. In other words, I tried to use :
SELECT CONCAT(CSurname, ' ', CName)
FROM Client;
In this way if I have a valid value for surname and a null value for name I obtain null. I use MySql, thanks.
If you want to avoid the problem with a leading space, then the easiest way is probably CONCAT_WS():
SELECT CONCAT_WS(' ', CSurname, CName)
FROM Client;
Unlike most other functions, CONCAT_WS() ignores NULL values (except for the separator), greatly simplifying this logic -- particularly when you are working with more than two columns.
Without it, the equivalent logic could be expressed as:
SELECT CONCAT(COALESCE(CONCAT(CSurname, ' '), ''), COALESCE(CName, ''))
Try the ifnull function
SELECT CONCAT(CSurname, ' ', IFNULL(CName,'')) FROM Client;
I don't have a local mysql installation to try it out but the IFNULL function should achieve what you need.
I have a NAME column and the data is stored like this in a MySql database:
Doe,John P
I would like to break it out into FNAME LNAME MNAME and FULLNAME.
If I don't want to tamper with the SQL table, should I create a view?
I know how to fix it in PHP with a function but I would rather the processing be done on the database server than the application server.
This is what I have so far. I thinking I need a compound query or something similar.
SELECT Name
, SUBSTRING_INDEX(Name,',',-1) As FNAME
, SUBSTRING_INDEX(Name,',',1) As LNAME
, SUBSTRING_INDEX(Name,' ',1) As MNAME
FROM people;
I'm having trouble grabbing the middle name and doing what I think should be CONCAT function to get FULLNAME.
It would be great if there was a way (maybe a conditional) to handle names in the database that didn't have middle names. (i.e. DOE,JOHN).
A view is a fine way to get the results you want for future queries. The defining query would be:
SELECT Name, SUBSTRING_INDEX(SUBSTRING_INDEX(Name, ',', -1), ' ', 1) As FNAME,
SUBSTRING_INDEX(Name, ',', 1) As LNAME,
SUBSTRING_INDEX(Name, ' ', -1) As MNAME
FROM people;
This will work assuming that the format is exactly correct as you describe it in the table. Small changes -- such as no middle name or a space after the comma -- would make the syntax more complicated.
Consider I am having tow fields in my table
field_profile_first_name_value field_profile_last_name_value
Victor Brecher
Abhi Jass
select field_profile_first_name_value, field_profile_last_name_value
from content_type_profile where field_profile_first_name_value LIKE '%Victor Bre%' OR
field_profile_last_name_value LIKE '%Victor Bre%'
I am having a auto complete text box.
When i enter the keyword as victor it will fetch the result. But if i give the first name and last name in the same time it will not produce the result.
That is if i give the keyword as Victor Brecher it will not produce the result.
How can i make to get the result if i enter first name and last name ?
How can i make it ?
Try :
select * from contracts
where lower(concat_ws(' ', field_profile_first_name_value, field_profile_last_name_value))
like lower('%Victor Bre%')
Well, even you don't need to use lower too. just use it simply.
select * from contracts where concat_ws(' ', field_profile_first_name_value,field_profile_last_name_value)
like '%Victor Bre%'
I would make use of soundex.
select * from contracts where SOUNDEX(concat_ws(' ', field_profile_first_name_value,field_profile_last_name_value)) = SOUNDEX('Victor Bre');
I suggest to use this code, so the search works also if the search input is the lastname before the name
SELECT
*
FROM
contracts
WHERE
CONCAT(firstname, ' ', lastname)) LIKE 'Victor Bre%'
OR CONCAT(lastname, ' ', firstname)) LIKE 'Victor Bre%';
Moreover, I tested this sql code with and without LOWER(), in mysql 5.7+ the search already do that.
I need to search on two fields using LIKE function and should match also in reverse order. My table uses InnoDB which dont have Full text search.
Consider the following case:
I have users table with first_name and last_name column. On it, there is a row with the following value:
{
first_name: 'Ludwig',
last_name: 'van Beethoven',
}
Cases:
Can search "Ludwig van Beethoven"
Can search "Beethoven Ludwig"
Can search "Ludwig"
Can search "Beethoven"
I tried this SQL statement but no luck.
SELECT CONCAT(first_name, ' ', last_name) as fullname
FROM users
WHERE fullname LIKE '%Ludwig van Beethoven%';
You need to re-state the concat expression in your where clause.
SELECT CONCAT(first_name, ' ', last_name) as fullname
FROM users
WHERE CONCAT(first_name, ' ', last_name) LIKE '%doe%';
Unfortunately "as" just create a column alias, not a variable that you can use elsewhere.
The Main Thing
Make sure you have a compound index on first_name and last_name. Otherwise, it's really easy to end up doing a full table scan regardless of how you approach this. So if you don't already have one, create one:
CREATE INDEX users_firstandlast ON users(first_name, last_name);
Syntax Options
Once that index is in place, you have some options:
Option 1: As Willis Blackburn said, repeat the CONCAT in your WHERE clause (because AS doesn't create a name you can use in the WHERE clause):
SELECT CONCAT(first_name, ' ', last_name) as fullname
FROM users
WHERE CONCAT(first_name, ' ', last_name) LIKE '%doe%';
Use EXPLAIN to check in your specific situation, but in my tests it says it uses the compound index, even though you're using a function in the WHERE clause.
Option 2: In this particular case, you can always just use two LIKE s in your WHERE clause:
SELECT CONCAT(first_name, ' ', last_name) as fullname
FROM users
WHERE first_name LIKE '%doe%' or last_name LIKE '%doe%';
Again this can make use of the compound index (whereas it won't make use of individual indexes on the first_name and last_name columns -- it would if you weren't leading with a wildcard, but according to EXPLAIN [and your mileage may vary, always check], in that case it goes with the table scan).
Option 3 In his answer, Andy says you can use HAVING for this. My read of the MySQL manual suggests it will first build the result set, and only then apply HAVING at the very end before sending it to the client, and so I'd be leery of this. But, in my quick and dirty tests, EXPLAIN tells me that if you have the compound index I mentioned above, the HAVING version does an index search, not a table scan. If your tests with real data bear that out, that may be a good option for you. This use of HAVING in this way is a MySQL extension (not standard), but then again, so is CONCAT so we're already into MySQL-specific stuff. :-) But again, double-check in your real life environment.
Conclusion
Create the index if you don't already have it, then I'd go with Option 2 if it's remotely a possibility; otherwise, option 1 unless you can find (or Andy can provide) a reference for the HAVING thing not building a massive interim result set (it would be really cool, if non-standard, if it didn't). Regardless, check with EXPLAIN, and test, in your specific environment.
SELECT * FROM users WHERE CONCAT(first_name, ' ', last_name) LIKE '%Ludwig%' OR CONCAT(last_name, ' ', first_name) LIKE '%Ludwig%';
All search cases where returned including 'Beethoven Ludwig'.
When you CONCAT() two columns the LIKE become case sensitive. So this should find you results but isn't optimal for performance:
SELECT CONCAT(first_name, ' ', last_name) AS fullname FROM users
WHERE LOWER(CONCAT(first_name, ' ', last_name)) LIKE LOWER('%doe%');
That's getting MySQL to do work on each row though.