Multitable query mysql - php

I am in process of creating multi variable & multi table search query for Job Portal. Got some success in creating following long query which gives results as required. I need to replace above highlighted red circle delimited values (which i created using GROUP_CONCAT function in following query) with follwoing table description values.
Note:- Delimited values are not in database field. I'am creating these using following query.
My other table structure is as follows:
+---------------------------------------------+
ID Description
+---------------------------------------------+
1 Delhi
2 Mumbai
3 Chennai
4 Kolkata
+----------------------------------------------+
Please help me to guide a way forward for one, rest i'll do it myself.
Select
a.user_id, g.username, a.mobile_no, a.location, a.DOB, a.current_CTC,
a.expected_CTC, a.work_exp, a.job_type, a.designation, a.Company_name,
a.keyskills, a.profile_headline, a.resume_path, a.Notice_period,
DATEDIFF(CURDATE(),Max(b.Login_date_time)) as Last_Login_days,
Max(b.Login_date_time) as Last_Available_on_site,
(Select GROUP_CONCAT(DISTINCT c.Education_ID ORDER BY c.Education_ID
SEPARATOR ', ') user_education from user_education c where a.user_id =
c.User_ID) as Education_ID,
(Select GROUP_CONCAT(DISTINCT d.FA_ID ORDER BY d.FA_ID SEPARATOR ', ') FA
from user_fa d where a.user_id = d.User_ID) as FA_ID,
(Select GROUP_CONCAT(DISTINCT e.Industry_ID ORDER BY e.Industry_ID
SEPARATOR ', ') Industry_ID from user_industry e where a.user_id =
e.User_ID) as Industry_ID,
(Select GROUP_CONCAT(DISTINCT f.Location_ID ORDER BY f.Location_ID
SEPARATOR ', ') Location_ID from user_preferred_locations f where
a.user_id = f.User_ID) as Preferred_Location_ID
from user_details a
left join login_history b on a.user_id = b.user_id
left join users g on a.user_id = g.id
left join user_education c on a.user_id = c.User_ID
left join user_fa d on a.user_id = d.User_ID
left join user_industry e on a.user_id = e.User_ID
left join user_preferred_locations f on a.user_id = f.User_ID
INNER JOIN locations h ON FIND_IN_SET(h.location_id, f.Location_ID)
WHERE MATCH(keyskills) AGAINST('MIS, Analysis' IN BOOLEAN MODE)
And YEAR(CURDATE()) - YEAR(DOB)>= 18 And YEAR(CURDATE()) - YEAR(DOB)<= 45
And work_exp >= 2 And work_exp <= 15
And a.current_CTC>=102 And a.current_CTC<=115
And a.industry IN (10001,10002,10004)
And a.functional_area IN(1001,1002,1003)
And a.location_preferred IN (1,2,3,4,6,7)
And Education_ID IN (1,5,7,8)
And a.job_type Like '%FTP%'
And Notice_period >= 15
And b.Login_date_time>=0
And a.mobile_no is not null
And resume_path is not null
group by a.user_id

Related

LIMIT LEFT join to last updated row from multiple rows

This is my code i am trying to left join the latest team data, not every piece of data. i have tried just using limit 1 but doesnt return anything
ORDER BY updated DESC LIMIT 1
this doesnt work
Any ideas?
$sql = "SELECT
events.id, events.time,events.status, events.home_team,events.away_team,events.league,
ht.id as home_id,ht.name as home_name,at.name as away_name,
statistics.home_goals,statistics.away_goals,statistics.time as game_time,
leagues.id as league_id,leagues.name as league_name,leagues.type as league_type,
country.name as country_name,country.logo,
hts.home_scored, ats.away_scored,
hts.home_conceeded,ats.away_conceeded,
hts.home_win,ats.away_win,
hts.home_15,ats.away_15,
hts.home_25,ats.away_25,
hts.home_btts, ats.away_btts,
hts.home_fts, ats.away_fts,
hts.home_cs, ats.away_cs,
hts.home_corners_for, ats.away_corners_for,
hts.home_corners_against, ats.away_corners_against,
hts.home_cards, ats.away_cards
FROM events
LEFT JOIN teams ht
ON ht.id = events.home_team
LEFT JOIN teams at
ON at.id = events.away_team
LEFT JOIN leagues
ON leagues.id = events.league
LEFT JOIN country
ON country.id=leagues.country
LEFT JOIN ( SELECT team,home_scored,home_conceeded,home_win,home_15,home_25,home_btts,home_fts,home_cs,home_corners_for,home_corners_against,home_cards FROM team_quick_stats ORDER BY updated DESC) hts
ON ht.id=hts.team
LEFT JOIN ( SELECT team,away_scored,away_conceeded,away_win,away_15,away_25,away_btts,away_fts,away_cs,away_corners_for,away_corners_against,away_cards FROM team_quick_stats ORDER BY updated DESC) ats
ON at.id=ats.team
LEFT JOIN statistics
ON statistics.event_id=events.id
WHERE (events.time BETWEEN $start AND $end) ORDER BY country.list_order, leagues.country ASC , leagues.id ASC, events.time ASC, home_name ASC";
Here's one way. Replace LEFT JOIN (SELECT team... etc....) ats with...
LEFT
JOIN
( SELECT x.team
, x.etc...
FROM team_quick_stats x
JOIN
( SELECT team
, MAX(updated) updated
FROM team_quick_stats
GROUP
BY team
) y
ON y.team = x.team
AND y.updated = x.updated
) ats...

JOIN not working in php mysql

I am working on a project with PHP and MySQL. I am trying to run a SQL query where I need to fetch data from 5 tables. I'm getting an error on my query.
$value = json_decode(file_get_contents('php://input'));
$estId = $value->estId;
$sql = 'SELECT establishments.id, establishments.name,
establishments.stay_value, establishments.latitude,
establishments.longitude, establishments.description,
establishments.address,
facilities.id, facilities.name,
accomodations.id,accomodations.name
FROM establishments
INNER JOIN (establishments_facilities
INNER JOIN facilities
ON establishments_facilty.facility_id = facilities.id)
ON establishments.id = establishments_facility.id
INNER JOIN (establishments_accommodations
INNER JOIN accommodations
ON establishments_accommodations.accommodation_d = accomodations.id)
WHERE establishments.id ="'.$estId .'" ';
$result = $conn->query($sql);
if($result->num_rows>0){
while($row = $result->fetch_assoc()){
$json_obj = $row;
}
$json_obj['success'] = true;
echo json_encode($json_obj);
}
My 5 tables are:
establishments
1 id
2 user_id
3 name
4 logo
5 description
6 email
7 latitude
8 longitude
9 stay_value
accomodations
1 id
2 name
facilities
1 id
2 name
establishments_accommodations
1 id
2 establishment_id
3 accommodation_id
establishments_facilities
1 id
2 establishment_id
3 facility_id
Any help will be appreciated.
The query you wrote is hard to read and you should use alias for better readability and also join syntax does not look correct, here is the query with proper alias
SELECT
e.id,
e.name,
e.stay_value,
e.latitude,
e.longitude,
e.description,
e.address,
f.id,
f.name,
a.id,
a.name
FROM establishments e
INNER JOIN establishments_facilities ef on e.id = ef.id
INNER JOIN facilities f ON ef.facility_id = f.id
INNER JOIN establishments_accommodations ea on ea.establishment_id = ef.establishment_id
INNER JOIN accommodations a ON ea.accommodation_d = a.id
WHERE e.id ={some value}
Now in PHP you may have something as
$sql = "
SELECT
e.id,
e.name,
e.stay_value,
e.latitude,
e.longitude,
e.description,
e.address,
f.id,
f.name,
a.id,
a.name
FROM establishments e
INNER JOIN establishments_facilities ef on e.id = ef.id
INNER JOIN facilities f ON ef.facility_id = f.id
INNER JOIN establishments_accommodations ea on ea.establishment_id = ef.establishment_id
INNER JOIN accommodations a ON ea.accommodation_d = a.id
where e.id = '".$estId."'";
Note that where e.id = '".$estId."'" is vulnerable to sq-injection, so better to use prepared statement.

MySQL subquery pulls multiple results

I've got repeating records with different 'manufacturer' fields. I'm trying to GROUP BY i.stocknumber but that only removes a record without collecting the other manufacturer result.
Some records have a NULL manufacturer field, and I've tried using GROUP_CONCAT in the subquery to elide the differing results for "manufacturer".
Here's my current query:
SELECT i.id,i.stocknumber,m.manufacturer
FROM inventory i
INNER JOIN makes mk on i.make = mk.id
INNER JOIN models md on i.model = md.id
INNER JOIN classes cl on i.class = cl.id
LEFT JOIN (
SELECT idm.id, idm.inventory_id, dm.manufacturer AS 'manufacturer'
FROM display_manufacturers dm
INNER JOIN inventory_display_manufacturers idm ON dm.id = idm.display_manufacturer_id
) m ON i.id = m.inventory_id
-- GROUP BY i.stocknumber
ORDER BY i.stocknumber
The result I get is:
Any thoughts on grouping the repeated records by concatenating the manufacturer field?
(NOTE: I already tried GROUP_CONCAT on the subquery)
DESIRED RESULT:
id | stocknumber | manufacturer
----------------------------------
946 | 011A | NULL
907 | 1001 | Sports Coach, Coachmen
1032 | 1001x | Sports Coach
etc....
Are you looking for this?
SELECT i.id, i.stocknumber, group_concat(distinct m.manufacturer) as manufacturers
. . .
GROUP BY i.stocknumber
EDIT:
This version explicitly uses your query as a subquery. It should not put all manufacturers on the same row:
select stocknumber, group_concat(distinct manufacturer) as manufacturers
from (SELECT i.id,i.stocknumber,m.manufacturer
FROM inventory i
INNER JOIN makes mk on i.make = mk.id
INNER JOIN models md on i.model = md.id
INNER JOIN classes cl on i.class = cl.id
LEFT JOIN (
SELECT idm.id, idm.inventory_id, dm.manufacturer AS 'manufacturer'
FROM display_manufacturers dm
INNER JOIN inventory_display_manufacturers idm ON dm.id = idm.display_manufacturer_id
) m ON i.id = m.inventory_id
) t
GROUP BY stocknumber ;
If what you are trying to do is removing the NULL fields, you just have to add a WHERE condition excluding the NULL fields
SELECT i.id,i.stocknumber,m.manufacturer
FROM inventory i
INNER JOIN makes mk on i.make = mk.id
INNER JOIN models md on i.model = md.id
INNER JOIN classes cl on i.class = cl.id
LEFT JOIN (
SELECT idm.id, idm.inventory_id, dm.manufacturer AS 'manufacturer'
FROM display_manufacturers dm
INNER JOIN inventory_display_manufacturers idm ON dm.id = idm.display_manufacturer_id
) m ON i.id = m.inventory_id
WHERE m.manufacturer IS NOT NULL
-- GROUP BY i.stocknumber
ORDER BY i.stocknumber

mysql select multitable - join

say i had the following tables
user_table
id username
1 abc
2 def
3 ghij
courses_table
id title
1 csc
2 math
3 syn
user_courses
user_id course_id
2 1
1 3
2 3
i want to select the username whos taking course 1 AND 3 ,
not at least 1 or 3 , i mean both 1 and 3
i've tried the following mysql queries
SELECT DISTINCT u.* FROM user_table as u LEFT JOIN user_courses as uc ON uc.user_id = u.id WHERE uc.course_id = 1 AND uc.course_id=3;
SELECT DISTINCT u.* FROM user_table as u LEFT JOIN user_courses as uc ON uc.user_id = u.id WHERE uc.course_id IN (1,3);
SELECT DISTINCT u.* FROM user_table as u LEFT JOIN user_courses as uc ON uc.user_id = u.id WHERE uc.course_id IN (1,3) AND uc.user_id = u.id ;
the first and third queries executed with no results shown , and the second one show all users who had at least course_id 1 or 3
if you are wondering why am i using the LEFT JOIN , this is because i need to join table's results , and the above line of code is just an example , and im using to get data from about 9 tables using the LEFT join .
any help please ? thanks
SELECT DISTINCT u.* FROM user_table as u LEFT JOIN user_courses as uc ON uc.user_id = u.id WHERE uc.course_id IN( 1,3) AND uc.user_id = 2 ";
this show me the result i want , its output "def" ,
but i can't use the user_id as a static value ( number 2 in this example )
This problem is called Relational Division
SELECT a.id, a.username
FROM user_table a
INNER JOIN user_courses b
ON a.id = b.user_ID
WHERE b.course_ID IN (1,3)
GROUP BY a.id, a.username
HAVING COUNT(*) = 2
SQL of Relational Division
If course_ID is not unique for every users considering that the user have retake the course, a DISTINCT keyword is needed to coung unique courses,
SELECT a.id, a.username
FROM user_table a
INNER JOIN user_courses b
ON a.id = b.user_ID
WHERE b.course_ID IN (1,3)
GROUP BY a.id, a.username
HAVING COUNT(DISTINCT b.course_ID) = 2
SQLFiddle Demo
OUTPUT
╔════╦══════════╗
║ ID ║ USERNAME ║
╠════╬══════════╣
║ 2 ║ def ║
╚════╩══════════╝
please try this:
SELECT
U.id,
U.username
FROM
user_courses UC
INNER JOIN user_table U
ON UC.`user_id` = U.`id`
WHERE UC.`course_id` = 1
OR UC.`course_id` = 3
GROUP BY U.`id`
HAVING COUNT(*) > 1

Optimizing a complex mysql query

The following query is taking 0.1313 seconds on phpmyadmin. Any way to optimize this to make things faster (say like to get it in 0.00XX seconds)? Index already added at columns that are doing the joinings.
SELECT m.id, m.civ, m.prenom, m.nom, m.sexe, m.depart, m.date_entree, m.date_sortie, m.login_userid, m.login_passwd, a.rank_id, r.rank_m, r.rank_f, d.user_id AS depID, c.nom AS cordo, z.rank
FROM `0_member` AS m
LEFT JOIN `0_area` AS a ON ( m.id = a.user_id
AND a.sec_id =2 )
LEFT JOIN `0_rank` AS r ON r.id = a.rank_id
LEFT JOIN `0_depart` AS d ON ( m.depart = d.depart
AND d.user_sec =2 )
LEFT JOIN `0_area` AS z ON ( d.user_id = z.user_id
AND z.sec_id =2 )
LEFT JOIN `0_member` AS c ON d.user_id = c.id
WHERE z.rank = 'mod'
ORDER BY nom
Your query has a final "WHERE" clause on the value being FOUND in the "Z" alias table with a rank of 'mod', yet your query is all LEFT JOINs indicating you want all members regardless of a possible match on the right side table you are joining to.
Additionally, you are joining downstream to the "z" table by depart and depart to a user ID, then re-joining directly to the '0_area' as A table directly on the user's ID which APPEARS it would be the same as found from the linking to the depart table to the 'z' table anyhow.
That said, and your member joins to depart and then to area...
My SUGGESTION (and I can rewrite the query as such) is to reverse the order of the query putting your Area table FIRST with an index on the "sec_id, rank" being available... I would have the key order based on whichever category had the smaller subset column first... so either SEC_ID, RANK or RANK, SEC_ID.
Then doing simple JOIN (not LEFT JOIN) to the other tables... At a minimum from:
SELECT STRAIGHT_JOIN
m.id,
m.civ,
m.prenom,
m.nom,
m.sexe,
m.depart,
m.date_entree,
m.date_sortie,
m.login_userid,
m.login_passwd,
a.rank_id,
r.rank_m,
r.rank_f,
d.user_id AS depID,
c.nom AS cordo,
z.rank
FROM
`0_area` AS z
JOIN `0_depart` AS d
on z.user_id = d.user_id
and d.user_sec = 2
JOIN `0_member` AS m
on d.depart = m.depart
AND z.user_id = m.id
LEFT JOIN `0_rank` AS r
on z.rank_id = .rid
WHERE
z.sec_id = 2
AND z.rank = 'mod'
ORDER BY
nom
In your original query, you had a join from
member
Links to Area (on member's user ID just to ensure the "sec_id = 2")
Since the new query is exclusively STARTING with the "area" table as "Z" alias, and THAT where clause is explicitly "sec_id = 2" value, you'll never need to backlink again...
Area (only SECID = 2 and rank = mod)
Links to Depart (on the User's ID)
Links to Members by (on the depart ID)
Try moving this statements " a.sec_id =2 ", "d.user_sec =2 ", " z.sec_id =2 " from ON sections to WHERE section like you already did with "z.rank = 'mod'". Like this:
SELECT m.id, m.civ, m.prenom, m.nom, m.sexe, m.depart, m.date_entree, m.date_sortie, m.login_userid, m.login_passwd, a.rank_id, r.rank_m, r.rank_f, d.user_id AS depID, c.nom AS cordo, z.rank
FROM `0_member` AS m
LEFT JOIN `0_area` AS a ON m.id = a.user_id
LEFT JOIN `0_rank` AS r ON r.id = a.rank_id
LEFT JOIN `0_depart` AS d ON m.depart = d.depart
LEFT JOIN `0_area` AS z ON d.user_id = z.user_id
LEFT JOIN `0_member` AS c ON d.user_id = c.id
WHERE z.rank = 'mod'
AND a.sec_id =2
AND d.user_sec =2
AND z.sec_id =2
ORDER BY nom

Categories