IF using inner join MySql? - mysql

How do I build a joint to select either table
Table jobs
Id | name | salary | company | type
1 | php | 17.850 | 5 | 1
2 | mysql | 4.500 | 89 | 2
2 | nodejs | 7.500 | 89 | 1
Table Company
Id | name | Area | status
1 | Facebook| Developer| 1
2 | Google | Manager | 1
Table Candidate
Id | name | City | phone
1 | Alan Kout | Nevada | 1 555 6666
2 | Wagner Mom | L.A. | 1 444 8965
My query mysql, inner join candidate or company
If type == 1 in table jobs INNER JOIN ON table company
If type == 2 in table jobs INNER JOIN ON table candidate
Example
SELECT * FROM table_jobs
IF(table_jobs.type == 1, INNER JOIN table_company, INNER JOIN table_candidate)
This is possible?

You can achieve this using a LEFT JOIN instead of an INNER JOIN:
SELECT *
FROM table_jobs tj
LEFT JOIN table_company tco ON tj.type = 1 AND tco.id = tj.id
LEFT JOIN table_candidate tca ON tj.type = 2 AND tca.id = tj.id
This will join to table_company where the type is 1, and table_candidate where the type is 2.
You can then SELECT whichever columns are needed from each table as appropriate.

Use left join and coalesce():
SELECT tj.*,
coalesce(co.name, ca.name) as name,
. . .
FROM table_jobs tj LEFT JOIN
table_company co
ON co.id = tj.id and tj.type = 1 LEFT JOIN
table_candidate ca
ON ca.id = tj.id and tj.type = 2;

If you want both joins in one result you can use the UNION operator
SELECT *
FROM table_jobs INNER JOIN table_company
WHERE table_jobs.type=1
UNION
SELECT *
FROM table_jobs INNER JOIN table_candidate
WHERE table_jobs.type=2

Related

MySQL Query JOIN 3 tables

Looking to join 3 tables, but having trouble on the last one.
members
ID | name
---------
1 | John
2 | Jane
3 | Jack
member_points (can have multiple transactions between members)
ID | date | id_from | id_to
---------------------------
1 | 8/8 | 1 | 2
2 | 8/8 | 1 | 2
3 | 8/8 | 3 | 2
member_ratings (one member can only rate another member, one time)
ID | id_from | id_to | rating
-----------------------------
1 | 2 | 1 | 5
Each member may rate each member only once, and can only rate the member they received a point from, based on the member_points table.
My current query achieves this, however I'm having difficulty introducing the 3rd table, that will include the rating accoringly.
Here is what I have so far:
$sql = '
SELECT *,
m.id AS id,
c1.id AS id_from,
c1.name AS name_from,
c2.id AS id_to,
c2.name AS name_to
FROM member_points AS m
JOIN members AS c1 ON m.id_from = c1.id
JOIN members AS c2 ON m.id_to = c2.id
and m.id_to='.$_SESSION["userid"].'
GROUP BY name_from';
My goal is join the 3rd table so I can call the associated rating.
ID | name_from | name_to | rating
----------------------------------
1 | 2 | 1 | 5
2 | 2 | 3 | pending
#Andrew you need to use a LEFT JOIN to join in the member_ratings table like this:
$sql = '
SELECT *,
m.id AS id,
c1.id AS id_from,
c1.name AS name_from,
c2.id AS id_to,
c2.name AS name_to,
IF(mr.rating IS NULL, 'pending', mr.rating) AS rating
FROM member_points AS m
JOIN members AS c1 ON m.id_from = c1.id
JOIN members AS c2 ON m.id_to = c2.id
and m.id_to='.$_SESSION["userid"].'
LEFT JOIN member_ratings AS mr ON mr.id_from = c1.id
AND mr.id_to = c2.id
GROUP BY name_from';
please let me know if this isn't what you need and I'll try to help you further.

Finding and Replacing Duplicates With Correct Data in MySQL

I have the following table with duplicate family IDs but different number of family members:
tbl_family
+------------+--------------+---------+
| familyID | Members | Location|
+------------+--------------+---------+
| 100 | 3 | xyz |
| 100 | 4 | xyz |
| 101 | 1 | abc |
| 101 | 2 | abc |
| 102 | 5 | efg |
| 103 | | hij |
+------------+--------------+---------+
I also have a second table where we verified the correct count of family members for the duplicates
tbl_verifier
+------------+--------------+---------+
| familyID | Members | Location|
+------------+--------------+---------+
| 100 | 3 | xyz |
| 101 | 2 | abc |
+------------+--------------+---------+
I want to create a view in mysql which will display the families without duplicates and maintain the row with the verified count of family members. The results should look as follows:
tbl_results
+------------+--------------+---------+
| familyID | Members | Location|
+------------+--------------+---------+
| 100 | 3 | xyz |
| 101 | 2 | abc |
| 102 | 5 | efg |
| 103 | | hij |
+------------+--------------+---------+
I am breaking the problem into several steps. I want to first select all those with matching Members then those with null Members
/* Step 1: Select only those that are matching family members count in
verifier and family */
select *
from tbl_family f
inner join
tbl_verifier v
ON f.familyID = v.familyID
WHERE f.Members = v.Members;
/* Step 2 : Select only those that have null number of rooms*/
select *
from tbl_family f
left join
tbl_verifier v
ON f.familyID = v.familyID
WHERE f.Members is null
Now am a bit stuck on how to proceed further.
Use UNION All to merge two result sets
select *
from tbl_family f
inner join tbl_verifier v ON f.familyID = v.familyID
and f.Members = v.Members
union all
select * from tbl_family f
left join tbl_verifier v ON f.familyID = v.familyID and and f.Members = v.Members
where v.familyID is null
how that sounds? I think it works
SELECT f.*
FROM tbl_family f, tbl_verifier v
WHERE (f.familyID = v.familyID AND f.Members = v.Members)
OR f.familyID NOT IN (SELECT familyID FROM tbl_verifier)
Use UNION ALL for your case, but it is better to add a location filter for same.
; with cte as (
select tbl_family.family_id, tbl_family.Members, tbl_family.location
from tbl_family
inner join tbl_verifier ON tbl_family.familyID = tbl_verifier.familyID
and tbl_family.Members = tbl_verifier.Members and tbl_family.Location = tbl_verifier.Location
union all
select tbl_family.family_id, tbl_family.Members, tbl_family.location
from tbl_family
left join tbl_verifier ON tbl_family.familyID = tbl_verifier.familyID
where tbl_family.Members is null
)
Select * from cte order by family_id
UNION ALL seems like a reasonable solution. The big question is how to get one row out of the first table if there are multiple rows.
Here is one method that uses MAX():
select v.familyID, v.Members, v.Location
from tbl_verifier v
union all
select f.familyID, max(f.Members), f.Location
from tbl_family f
where not exists (select 1
from tbl_verifier v
where v.familyId = f.familyId
);
Your question is unclear as to whether families can be in multiple locations. If so, you need to include location in the correlation clause.
From the different answers posted above, i was able to come up with the following script which worked
; with cte as (select f.familyID,
f.Members,
f.Location
from tbl_family f
inner join tbl_verifier v ON f.familyID = v.familyID
and f.Members = v.Members
union all
select f.familyID,
f.Members,
f.Location from tbl_family f
left join tbl_verifier v ON f.familyID = v.familyID
where f.Members is NULL
)
SELECT * INTO temp1 FROM cte
SELECT * FROM tbl_family WHERE familyID NOT IN (SELECT familyID FROM temp1)
UNION ALL
SELECT * FROM temp1
ORDER BY familyID

JOIN 2 SQL table (1 field at table 1 replace more than 1 field at the other table)

Someone please help me.
I have 2 tables, My Database is MySQL
table1
user_id | username
------- | --------
1 | joni
2 | adam
3 | jerry
4 | Dino
table2
dokumen_id | create_by | update_by | last_access_by |
doc_001 | 2 | 1 | 2 |
doc_002 | 3 | 2 | 1 |
doc_003 | 1 | 1 | 4 |
I want to join 2 tables in one query and the result like this
dokumen_id | create_by | update_by | last_access_by |
doc_001 | adam | joni | adam |
doc_002 | jerry | adam | joni |
doc_003 | joni | joni | dino |
how do i write the query?
many thanks for the help.
You need to Join table1 thrice
SELECT t2.dokumen_id,
c.username AS create_by,
u.username AS update_by,
l.username AS last_access_by
FROM table2 t2
LEFT JOIN table1 c
ON t2.create_by = c.user_id
LEFT JOIN table1 u
ON t2.update_by = u.user_id
LEFT JOIN table1 l
ON t2.last_access_by = l.user_id
Left Outer Join is used to return all the records from table2, a user might have present in create_by but not in last_access_by in that case Inner join will filter the records who is not present in create_by
Join the table1 three times with table2
select t1.dokumen_id,
tc.username create_by,
tu.username update_by,
ta.username last_access_by
from table2 t1
left outer join table1 tc
on tc.user_id = t1.create_by
left outer join table1 tu
on tu.user_id = t1.update_by
left outer join table1 ta
on ta.user_id = t1.last_access_by;
SELECT * FROM table1
LEFT JOIN table2
ON table1.user_id=table2.last_access_by;
You need to Join table1 thrice
SELECT t2.dokumen_id,
c.username AS create_by,
u.username AS update_by,
l.username AS last_access_by
FROM table2 t2
LEFT JOIN table1 c
ON t2.create_by = c.user_id
LEFT JOIN table1 u
ON t2.update_by = u.user_id
LEFT JOIN table1 l
ON t2.last_access_by = l.user_id

Select * as well as count/sum from another table

I am trying to write a MySQL query to select all rows from table a, as well as information from table b, while also querying the count and sum of values in another table c, for each row of a.
I will try to break that down a bit better, here is a simplified version of my tables:
Table A
+---------+----------+-----------+
| id | name | bid |
+---------+----------+-----------+
| 1 | abc | 1 |
| 2 | def | 1 |
| 3 | ghi | 2 |
+--------------------------------+
Table B
+---------+----------+
| id | name |
+---------+----------+
| 1 | STAN |
| 2 | UCLA |
+--------------------+
Table C
+---------+----------+-----------+
| id | aid | cnumber |
+---------+----------+-----------+
| 1 | 1 | 40 |
| 2 | 1 | 20 |
| 3 | 2 | 10 |
| 4 | 3 | 40 |
| 5 | 3 | 20 |
| 6 | 3 | 10 |
+--------------------------------+
What I need is a query that will return rows containing
a.id | a.name | b.id | b.name | SUM(c.cnumber) | COUNT(c.cnumber)
I am not sure if such a thing is even possible in MySQL.
My current solution is trying to query A + B Left Join and then UNION with A + C Right Join. It's not giving me the results I'm looking for however.
Thanks.
edit:
current query re-written for this problem:
SELECT
a.id,
a.name,
b.id,
b.name
"somecolumn" as dummy_column
"somecolumn1" as dummy_column1
FROM a
LEFT OUTER JOIN b ON a.b.id = b.id
UNION
SELECT
"somecolumn" as dummy_column
"somecolumn1" as dummy_column1
"somecolumn2" as dummy_column2
"somecolumn3" as dummy_column3
COUNT(c.cnumber) AS ccount
SUM(c.cnumber) AS sum
FROM a
RIGHT OUTER JOIN c ON a.id = c.a.id;
Unfortunately MySQL doesn't have FULL OUTER JOIN, and this is my temporary work around, although I don't think it's even the proper idea.
My desired output is all the rows from table A with some info from table B, as well as their totaled inputs in table C.
edit2:
SELECT
a.id,
a.name,
b.id,
SUM(c.cnumber) as totalSum,
(SELECT count(*) FROM c as cc WHERE cc.aid = a.id) as totalCount
FROM
a
LEFT JOIN b ON a.bid = b.id
LEFT JOIN c ON c.aid = a.id;
For future similar questions, solution:
SELECT
a.id AS aid,
a.name,
b.id,
(SELECT SUM(c.rating) FROM c WHERE c.aid = aid) AS totalSum,
(SELECT COUNT(c.rating) FROM c WHERE c.aid = aid) AS totalCount
FROM
a
LEFT JOIN b ON a.bid = b.id;
Your query should be :-
SELECT
a.id,
a.name,
b.id,
(SELECT SUM(c.cnumber) FROM c as cd WHERE cd.aid = a.id) as totalSum,
(SELECT count(*) FROM c as cc WHERE cc.aid = a.id) as totalCount
FROM
a
LEFT JOIN b ON a.bid = b.id
LEFT JOIN c ON c.aid = a.id;
It may help you.
I have tried your example.
SELECT * ,
(SELECT SUM(cnumber) FROM `table_c` WHERE `table_c`.`iaid` = `table_a`.`id`),
(SELECT COUNT(cnumber) FROM `table_c` WHERE `table_c`.`a.id` = `table_a`.`id`)
FROM `table_a`,`table_b` WHERE `table_b`.`id` = `table_a`.`b.id`
i got the Following output.

How to join 5 tables with IF conditions

I want to join 5 tables through book_id. I tried:
SELECT booked_room_info . * , booking_info . * , hotel_info.name as
hotelname,hotel_info.address as hoteladdress,hotel_info.contact as
hotelcontact , personal_info . *,room_registration.room_name as
roomname,room_registration.price as roomprice,room_registration.price as
roomprice,room_registration.description as
roomdescription,room_registration.image as roomimage
FROM booked_room_info
JOIN booking_info ON booking_info.booking_id = booked_room_info.booking_id
JOIN hotel_info ON hotel_info.id = booking_info.hotel_id
JOIN personal_info ON personal_info.booking_id = booked_room_info.booking_id
JOIN room_registration ON room_registration.hotel_id = booking_info.hotel_id
WHERE booked_room_info.booking_id= 1
But if i have 2 booking on booking_id = 1 but it fetched 10 result. I think I should make a if condition like. If (booked.room_type && book_info.hotel_id) is same then only fetch rows from room_registration but how can I aacomplish it.
booked_room_info
------
id | booking_id | room_type | check_in | check_out
1 | 1 | delux | 2015/1/2 | 2015/1/5
booking_info
---------
id | booking_id | hotel_id | user_id
1 | 1 | 2 | 1
hotel_info
----------
id | name | address | user_id
2 |palm hotel | newyork | 1
personal_info
-------------
id |full_name | address | nationality | booking_id
1 | sushil stha | new york | smth | 1
room_registration
-----------------
id | room_name | price | image | hotel_id | user_id
1 | delux | 1000 |room.jpg | 2 | 1
There is an error in your last join:
JOIN room_registration ON room_registration.hotel_id = booking_info.hotel_id
You are joining these tables using hotel_id column. There are probably 5 rows in room_registration table with hotel_id=2. So after joining you receive 2*5=10 rows instead of expected 2.
So you should join with this table in different way.
If you want to join every row with exacly one row from room_registration table then you have to specify more precise join condition.
To join room_registration table properly you may add room_registration_id column to booking_info table. Then you can join using:
JOIN room_registration ON room_registration.id = booking_info.room_registration_id
Use INNER JOIN's, removed the duplicate field.
SELECT
bri.*,
bi.*,
hi.name AS hotelname, hi.address as hoteladdress, hi.contact AS hotelcontact,
pi.*,
rr.room_name AS roomname, rr.price AS roomprice, rr.description AS roomdescription, rr.image AS roomimage
FROM booked_room_info bri
INNER JOIN booking_info bi ON bri.booking_id = bi.booking_id
INNER JOIN hotel_info hi ON bi.hotel_id = hi.id
INNER JOIN personal_info pi ON bri.booking_id = pi.booking_id
INNER JOIN room_registration rr ON bi.hotel_id = rr.hotel_id
WHERE bri.booking_id = 1