Mysql query that searches in table with no reference to current search? - mysql

I have a HTML input field that searches for names in a MySql table and drops down a DIV that displays first 15 records found.
The names are displayed with DISTINCT (so unique values).
If I type in for example adr in the text input box, it will display first 15 matches for "%adr%".
What I need to do now (and I can't get any luck with it), is look for 2 different types of codes (located in codes_table_1 and codes_table_2), in the same text input field (so expanding my existing query).
The structure of the 2 codes_tables would be this below (each having id and name as columns):
code_id_1 | code_name_1
1 XK112932
2 XK082192
3 ...
and
code_id_2 | code_name_2
1 GG882931
2 GG014253
3 ...
So I need to find a way to add to my DISTINCT rows containing unique persons with their phone and addresses, these codes, as in adding new rows to the result query.
For example if instead of a name I look for "KD139", I need to get 1st 15 occurences that begin / or have inside the code KD139, looking this up into the 2 codes tables.
Here's my query for unique names :
SELECT DISTINCT CONCAT(COALESCE(customer.last_name,''), ' ',
COALESCE(customer.first_name,'')) as fullName,
customer.first_name,
customer.last_name,
customer.email,
address.phone,
customer.customer_id
FROM customer
LEFT JOIN address
ON address.address_id = customer.address_id
WHERE CONCAT(COALESCE(customer.first_name,''), ' ', COALESCE(customer.last_name,'')) LIKE :search OR
CONCAT(COALESCE(customer.last_name,''), ' ', COALESCE(customer.first_name,'')) LIKE :search OR
customer.business_name LIKE :search OR
customer.email LIKE :search OR
address.phone LIKE :search
LIMIT 15
UPDATE (a solution that works!) :
(SELECT DISTINCT
customer.customer_id,
CONCAT(COALESCE(customer.last_name,''), ' ', COALESCE(customer.first_name,'')) as fullName,
customer.email,
address.phone
FROM customer
LEFT JOIN address
ON address.address_id = customer.address_id
INNER JOIN th_table
WHERE CONCAT(COALESCE(customer.first_name,''), ' ', COALESCE(customer.last_name,'')) LIKE :search OR
CONCAT(COALESCE(customer.last_name,''), ' ', COALESCE(customer.first_name,'')) LIKE :search OR
customer.business_name LIKE :search OR
customer.email LIKE :search OR
address.phone LIKE :search
ORDER BY fullName ASC
LIMIT 15)
UNION ALL
(SELECT code1_table.code1_id,
code1_table.code1_number,
'TH_TABLE' as email,
Null as phone
FROM code1_table
WHERE code1_table.code1_number LIKE :search
ORDER BY code1_table.code1_number ASC
LIMIT 15)
UNION ALL
(SELECT code2_table.code2_id,
code2_table.code2_number,
'CODE2_TABLE' as email,
Null as phone
FROM code2_table
WHERE code2_table.code2_number LIKE :search
ORDER BY code2_table.code2_number ASC
LIMIT 15)

Let's say you want to search artist and song tables together for search terms. You might try someting like this.
SELECT *
FROM (
SELECT 'artist' as type,
first as first, last as last, label as tag
FROM artist
WHERE first LIKE '%searchterm%'
OR last LIKE '%searchterm%'
OR label LIKE '%searchterm%'
UNION ALL
SELECT 'song' as type,
title as first, '' as last, '' as tag
FROM song
WHERE title LIKE '%searchterm%'
)
This gets you a result set with information from both tables in it, formatted so UNION ALL makes sense. You can then filter and order the results appropriately for your application.
I offer only one guarantee on this sample code: It will be slow. LIKE '%thing' is a notorious performance antipattern.

Related

sql IN keyword and multiple input columns - how to combine into a single column

I have some sql that is not doing what I want. I would like the CONCAT statement to produce a single list of id numbers. As it is now I get a column that has in it "number, number". I want one column of integers. I am using the IN keyword.
SELECT DISTINCT visible
, num
, date_now
, show_message
, show_exercise
, show_workout
, picture_large
FROM feed
WHERE feed.from_user_id IN
( SELECT DISTINCT
CONCAT(friends.user_id, ', ', friends.friend_user_id )
FROM friends
WHERE friends.user_id = 1
OR friends.friend_user_id = 1
)
ORDER BY feed.date_now DESC
How do I properly make use of the IN keyword with multiple columns as an input??
You are looking for the function group_concat() instead of concat() and you want to group by whatever that will generate a single row with the values you want.
Not sure I understand your question correctly. But is this what you are looking for?
SELECT DISTINCT
visible, num, date_now, show_message, show_exercise, show_workout, picture_large
FROM feed WHERE feed.from_user_id IN
( SELECT friends.user_id
FROM friends
WHERE friends.user_id = 1
union
SELECT DISTINCT
friends.friend_user_id
FROM friends
friends.friend_user_id = 1
)
ORDER BY feed.date_now DESC

Ordering mysql query results by location

I've a search bar to search for other users by their name or username, and that's easy to do, but what I'm trying to do is that in case more that one user have the same name that you're searching for I want to show first the closest one to you, so that first will appear the users with that name who are in the same city as u, then the same country, and then the rest of the world, I'am able to achieve the required result with multiple queries, but is it achievable with one query?
NOTE: the user table that I'm using for the search contains Username, FName, LName, CountryCode, CityID.
these are the queries I'm using now:
Select user.USERNAME, AVG(userrating.RATING) as Avg_Rating
from user LEFT JOIN userrating on user.USERNAME = userrating.USERNAME
WHERE CONCAT (user.FNAME, " ", user.LNAME) like '%Searched Name%' and user.CITYID = User's_City_ID
GROUP by user.USERNAME
ORDER by Avg_Rating
then I use the same query but for the country of the user and excluding the previously used city:
Select user.USERNAME, AVG(userrating.RATING) as Avg_Rating
from user LEFT JOIN userrating on user.USERNAME = userrating.USERNAME
WHERE CONCAT (user.FNAME, " ", user.LNAME) like '%Searched Name%' and user.CountryCode = User's_Country_Code and not user.CITYID = User's_City_ID
GROUP by user.USERNAME
ORDER by Avg_Rating
and then the same but excluding the whole country that I used in the prev. query:
Select user.USERNAME, AVG(userrating.RATING) as Avg_Rating
from user LEFT JOIN userrating on user.USERNAME = userrating.USERNAME
WHERE CONCAT (user.FNAME, " ", user.LNAME) like '%Searched Name%' and not user.CountryCode = User's_Country_Code
GROUP by user.USERNAME
ORDER by Avg_Rating
and then I'm combining the results of the three queries.
Starting from your current query (called « other » in the below SQL), you want to JOIN on the record that corresponds to the current user (called « me ») and then use a special ORDER BY clause to show the closest matching records first, using a CASE construct.
This assumes that « username » can be used to uniquely identify the current user.
SELECT
other.username
FROM userrating other
INNER JOIN userrating me on me.username = 'bar'
WHERE
CONCAT (other.FNAME, " ", other.LNAME) like '%Searched Name%'
ORDER BY
CASE
WHEN other.cityid = me.cityid THEN 0
WHEN other.countryid = me.countryid THEN 1
ELSE 2
END,
other.username
You need to replace 'bar' with current username.
It's difficult to do this exactly with one query, but you can do something like this:
SELECT * FROM users WHERE username LIKE '%searchkey%' OR fname LIKE '%searchkey%' OR lname LIKE '%searchkey%' OR countryid LIKE '%searchkey%' OR cityid LIKE '%searchkey%'
Here you can read more about the LIKE Operator.

MySQL excutes select after where clause

This query gives an error unknown column company in where clause. I found that where clause runs first and select runs next. That could be the error here. But i dont know how to correct this in order to get company in result set.
SELECT trnsdriverid,
name,
(SELECT transcompany.name
FROM transcompany,
transcompdriver
WHERE transcompany.trnscompid = transcompdriver.trnscompid) AS 'company',
address,
dob,
license,
telephone
FROM transcompdriver
WHERE ? LIKE 'All'
OR name LIKE '%"+keyword+"%'
OR company LIKE '%"+keyword+"%'
OR trnsdriverid LIKE '%"+keyword+"%'
You can't reference column aliases in where statements. You should rewrite this query to use a JOIN and then do your filtering on the actual TransCompany.name column, for example:
select
d.trnsDriverID
,d.name
,c.name as [Company]
,d.address
,d.dob
,d.license
,d.telephone
from
TransCompDriver d
join
TransCompany c
on
c.trnscompid = d.trnscompid
where
? = 'All'
or
d.name like '%" + keyword + "%'
or
c.name like '%" + keyword + "%'
or
d.trnsDriverID like '%" + keyword + "%'
Also, don't use LIKE where a simple equality operator would do. I changed the query above to use = 'All'.
You should really be doing this using a join rather than a subselect. I would recommend this:
SELECT
d.trnsDriverID,
d.name,
c.name AS `company`,
d.address,
d.dob,
d.license,
d.telephone
FROM
TransCompDriver AS d
INNER JOIN TransCompany AS c
ON d.trnsCompID = c.trnsCompID
WHERE
? like 'All'
OR d.name LIKE '%"+keyword+"%'
OR `company` LIKE '%"+keyword+"%'
OR d.trnsDriverID LIKE '%"+keyword+"%'
The sub-query that pulls the column "company" does not have matching number of rows, try the join statement instead
select trnsDriverID, name, t1.name AS company, address, dob, license, telephone
from TransCompDriver JOIN (select trnsDriverID, name,
(select TransCompany.name from TransCompany LEFT JOIN TransCompDriver
ON TransCompany.trnsCompID=TransCompDriver.trnsCompID) AS t1
where ? like 'All' or name like '%"+keyword+"%' or company like '%"+keyword+"%'
or trnsDriverID like '%"+keyword+"%'

MySQL SELECT INNER JOIN and LIKE

I whant to do something like this:
SELECT
s.name,
COUNT(r.request_log_id) AS NumberOfRequests
FROM
station AS s
LEFT JOIN request_log AS r ON r.requested LIKE '%s.station_id%'
GROUP BY 1
But this gives 0 in the NumberOfRequests and i think it is becouse its hardcoded s.station_id its running LIKE on.
Does anyone know how i can do this?
For your information, r.requested is a string whit some data in it and one example is
/StationInfo - stationID = "262" - Status = 0
So it is the staitonid i whant to get LIKE on and cound how many rows in request_log table it is in that have the station id for the first table named station
First approach:
SELECT
s.name,
COUNT(r.request_log_id) AS NumberOfRequests
FROM
station AS s
LEFT JOIN request_log AS r
ON r.requested LIKE concat( '%',s.station_id, '%')
GROUP BY 1
be careful with this non equijoin.
see you.

mysql left join, how to write such query?

I have
first:
select url from urls where site = '$value' order by url
second:
select id, widget_name from widgets where display_urls LIKE 'urls.url' and is_father=1 order by id
Third:
select id, widget_name from widgets where display_urls RLIKE 'urls.url' and is_father=0 order by id
Fourth:
select id, widget_name, father_widget from widgets where father_widget = 'widgets.id' order by id
The fourth query must only take widgets.id from second query
the second and third queries take the value of urls.url from the first query
how to write all those in one mysql query using left join ?
Thanks in advance for your answers :)
SELECT w.id, w.widget_name, c.*
FROM urls
JOIN widgets w
ON w.display_urls LIKE urls.url
OR w.display_urls RLIKE urls.url
LEFT JOIN
widgets с
ON c.father_widget = w.id
AND w.display_urls LIKE urls.url
AND w.display_urls NOT RLIKE urls.url
WHERE site = $value
ORDER BY
url
This will select children only for those widgets that are LIKE but nor RLIKE the corresponding url.