Searching two mysql columns added together for one variable - mysql

I currently have a search form which should allow a user to search for a customers full name and it will return the row.
For Example: A user searches for "Mr. N Mallow" and it will return the row which matches that query. Since I am new to MySQL I need some help, I've tried + but that has no effect, probably because it's not standard mysql or something like that.
select *
from mooring
left join customer
on mooring.assignedTo = customer.id
where mooring.Number like \"$var\"
or (customer.TitleName + customer.Surname = '$var')
Any suggestions?

select * from mooring
left join customer on mooring.assignedTo = customer.id
where mooring.Number like \"$var\" OR (customer.TitleName + customer.Surname = '$var')
Try CONCAT_WS or CONCAT, which join strings together (the first version is "with separator"):
CONCAT(customer.TitleName,' ',customer.Surname)
or
CONCAT_WS(' ',customer.TitleName,customer.Surname)

Related

How could I make a fullname search work with a seperate last and firstname?

I'm new to SQL and I'm trying to make a basic query work.
This is the table and it's layout that I'm trying to search against:
https://prnt.sc/20wj54g
What I'm aiming to do is have a search term input, then have the input be used to search for names in the database by fullname.
This is the current query I have now:
SELECT *
FROM personnel p
LEFT JOIN department d ON (d.id = p.departmentID)
LEFT JOIN location l ON (l.id = d.locationID)
WHERE p.firstName LIKE '%Robert Heffron%' OR p.lastName LIKE '%Robert Heffron%';
This doesn't work as there is no last or firstname which contains the whole string "Robert Heffron" however this means if the user typed in that string looking for that person by the full name they wouldn't find them.
I'm currently using PHP and JS to display the data but I'm struggling with the SQL part.
If anyone could help I'd be very grateful.
This is not a good solution for performance, but if you want to solve the problem only using SQL, you can try this:
SELECT *
FROM personnel p
LEFT JOIN department d ON (d.id = p.departmentID)
LEFT JOIN location l ON (l.id = d.locationID)
WHERE LOWER(CONCAT(p.firstName, p.lastName)) LIKE LOWER(REPLACE('%Robert Heffron%', ' ', '%'))
OR LOWER(CONCAT(p.lastName, p.firstName)) LIKE LOWER(REPLACE('%Robert Heffron%', ' ', '%'));
Field concatenation is used to find a concatenated input value, and different combinations of OR concatenation are used to be independent of the order in which the first and last name are entered. Convert to lowercase - for case insensitive searches. We replace spaces with a % character to search for concatenated field values without worrying about spaces.
I would suggest adding a full name field to your database table and whenever you create a "personnel" in your code, you concatenate the first and last name:
Fullname = Firstname + " " + Lastname
if you don't like this, maybe use a string split function (in php it might be .explode()) and then adding WHERE OR statements for each substring for first and last name.
Use the following combination to find people whose name is Robert and whose last name is Heffron
Just find Robert Heffron
WHERE p.firstName LIKE '%Robert%' AND p.lastName LIKE '%Heffron%';
find all first names that have Robert and all last names that have Heffron
WHERE p.firstName LIKE '%Robert%' OR p.lastName LIKE '%Heffron%';
A solution that wouldn't ask you to change the table and having only one input variable could be something like this:
DECLARE #FullName AS VARCHAR(100)
SET #FullName = 'Robert Heffron'
SET #FullName = REPLACE(#FullName, ' ', '.')
SELECT....
WHERE p.firstname LIKE '%'+ ParseName(#FullName, 2) + '%' OR
p.firstname LIKE '%'+ ParseName(#FullName, 1) + '%' OR
p.lastnameLIKE '%'+ ParseName(#FullName, 2) + '%' OR
p.lastname LIKE '%'+ ParseName(#FullName, 1) + '%'
Downside in my opinion is if the user enters weird amount of spaces in the name. I have tested replacing the array number 1 or 2 in the ParseName with a number which was impossible, like 7, and it basically just ignores it.. no errors thrown or whatever. If you use this, you could test it on your side just to make sure tho.
You can use concat for the columns and can use "HAVING" clause on the concatenated column. I hope it will work for you.
SELECT * FROM personnel p LEFT JOIN department d ON (d.id = p.departmentID) LEFT JOIN location l ON (l.id = d.locationID) HAVING CONCAT(firstName,' ',lastName) LIKE '%Robert Heffron%';
I hope this snippet will work for you.

Searching SQL database and CONCAT data

New to php and sql so i will try to explain:
I have a SEARCH field in PHP and i am trying to search by 'ProposalName' that match with what the user enters.
This prints out fine:
SELECT
rec_proposal.ProposalID,
ProposalName,
Status,
researcher.FirstName,
researcher.LastName,
reviewer.FirstName as revFirstName,
reviewer.LastName as revLastName,
reviewer.UserID as revUserID,
review.ReviewDate as revDate,
rec_proposal.DateSubmitted
FROM rec_proposal
INNER JOIN User AS researcher
ON rec_proposal.userid = researcher.UserID
LEFT JOIN review
ON rec_proposal.ProposalID=review.ProposalID
LEFT JOIN User as reviewer
ON review.UserID=reviewer.UserID
But now using all the columns I need the above code to do something like this
SELECT * FROM rec_proposal WHERE CONCAT (ProposalName) LIKE'%test%'
SO if user enters the word 'test' you would see ProposalName that contains the words test
Just add your WHERE clause, it should work. And as scaisEdge noted in their comment, you don't need CONCAT() if you are just evaluating a single column :
SELECT
rec_proposal.ProposalID,
ProposalName,
Status,
researcher.FirstName,
researcher.LastName,
reviewer.FirstName as revFirstName,
reviewer.LastName as revLastName,
reviewer.UserID as revUserID,
review.ReviewDate as revDate,
rec_proposal.DateSubmitted
FROM rec_proposal
INNER JOIN User AS researcher
ON rec_proposal.userid = researcher.UserID
LEFT JOIN review
ON rec_proposal.ProposalID=review.ProposalID
LEFT JOIN User as reviewer
ON review.UserID=reviewer.UserID
WHERE rec_proposal.ProposalName LIKE '%test%'

JOIN on keys that don't have the same value

I am trying to do an INNER JOIN on two tables that have similar values, but not quite the same. One table has a fully qualified host name for its primary key, and the other the hosts short name, as well as the subdomain. It it safe to assume that the short name and the subdomain together are unique.
So I've tried:
SELECT table1.nisinfo.* FROM table1.nisinfo INNER JOIN table2.hosts ON (table1.nisinfo.shortname + '.' + table1.nisinfo.subdomainname + '.domain.com') = table2.hosts.fqhn WHERE table2.hosts.package = 'somepkg';
This doesn't return the results I expect, it returns the first result hundreds of times. I'd like to return distinct rows. It takes a long time to run as well.
What am I doing wrong? I was thinking of running a subquery to get the hostnames, but I don't know what the right path from here is.
Thank you!
You can use group by in your query so you can achieve the desired results you want
please see this two links
Group by with 2 distinct columns in SQL Server
http://www.sqlteam.com/article/how-to-use-group-by-with-distinct-aggregates-and-derived-tables
Try putting your results into a temp table and then view the table to make sure that the columns are as expected.
SELECT table1.nisinfo.*, table1.nisinfo.shortname + '.' + table1.nisinfo.subdomainname + '.domain.com' AS ColID
INTO #temp
FROM table1.nisinfo;
Select *
from #temp INNER JOIN table2.hosts ON ##temp.ColID = table2.hosts.fqhn
WHERE table2.hosts.package = 'somepkg'
;
Put a Group By clause at the end of the second statement
So in this case, I used a subquery to get the initial results, and then used a join.
SELECT table1.nisinfo.* FROM table1.nisinfo JOIN (SELECT distinct(fqhn) FROM table2.hosts WHERE package = 'bash') AS FQ ON ((SUBSTRING_INDEX(FQ.fqhn, '.', 1)) = table1.nisinfo.shortname);

(mysql) how to add wildcard on where condition when joining with another table?

i have one query that need some changes, and i don't get any clue to do this :
this is my query :
select * from user_data a
left join user_group b
on (a.role like b.role)
actually role value in userdata is (varchar)'staff'
and role value in group is (varchar)'staff;security;finance'
so i don't get result what i expected ..
i imagine the query should be similar to this :
select * from user_data a
left join user_group b
on (b.role like a.role+";%") // using wildcard
and i still don't know the right query using wildcard to this case
any one can help?
You can use CONCAT:
select * from user_data a
left join user_group b
on (b.role like CONCAT(a.role,";%")) // using wildcard
Note - does b.role only have to match a.role at the beginning? what if it was security;staff;finance? You could do CONCAT('%',a.role,'%').
You could do CONCAT('%','a.role','%') to handle matching a.role at any position, but only if you can be sure that you won't have nested roles.
For example: if b.role is staff and a.role is finance;gardenstaff;security, then this row will be returned from the query even though the role is gardenstaff and not staff.
As an alternative, you can use RLIKE instead of LIKE. This is basically a regular-expressions verson of LIKE.
In particular, the regex [[:<:]]staff[[:>:]] will match the whole word staff. The [[:<:]] and [[:>:]] stand for word boundaries, which stop you from matching the staff in gardenstaff.
So, your query could be:
select * from user_data a
left join user_group b
on (b.role RLIKE CONCAT('[[:<:]]',a.role,'[[:>:]]'))
And this would work for b.role being anywhere in the semicolon-separated a.role.

Can anyone help me with a complex sum, 3 table join mysql query?

Hey guys I have a query and it works fine, but I want to add another table to the mix. The invite table I want to add has two fields: username and user_invite. Much like this site, I am using a point system to encourage diligent users. The current query which is displayed below adds the up votes and down votes based on the user in question: $creator. I want to count the number of entries for that same user from the invite table, and add 50 for each row it finds to the current output/sum of my query. Is this possible with one query, or do I need two?
"SELECT *,
SUM(IF(points_id = \"1\", 1,0))-SUM(IF(points_id = \"2\", 1,0)) AS 'total'
FROM points
LEFT JOIN post ON post.post_id=points.points_id
WHERE post.creator='$creator'"
This should work :
SELECT *,**SUM(IF(points_id = "1", 1,0))-SUM(IF(points_id = "2", 1,0))+(select count(*)*50
from inivite where username='$creator') AS 'total'**,
FROM points LEFT JOIN post ON post.post_id=points.points_id WHERE post.creator='$creator'"
Assuming that there might be no correspondence in invite table, I used outer join and coalesce:
SET #good='1', #bad='2', #creator='$creator';
SELECT *,
SUM(IF(points_id=#good, 1,0))-SUM(IF(points_id=#bad, 1,0))+COALESCE(inv_cnt, 0) * 50) AS total
FROM points
LEFT JOIN post
ON post.post_id=points.points_id
LEFT OUTER JOIN (SELECT username, COUNT(user_invite) as inv_cnt
FROM invite
GROUP BY username) invites
ON post.creator = invites.username
WHERE post.creator=#creator;
Designing this query with limited knowledge of the schema...
SELECT *,
SUM(IF(points_id = \"1\", 1,0))
-SUM(IF(points_id = \"2\", 1,0))
+ 50 * COUNT(invite.user_invite) AS 'total' <--
FROM points
LEFT JOIN post ON post.post_id=points.points_id <--
LEFT JOIN invite ON post.creator = invite.user_invite
WHERE post.creator='$creator'
The important thing here is the extra lines, which I've marked with "<--". One is for JOINing your two tables together, the other is to modify the argument of the SUM function.
Post back if this doesn't work.