join 3 tables if 3rd table does not have that value - mysql

Table 1
id , userid, eventid , name
table 2
eventid , zoneid , userid
table 3
eventid , userid, status
if all three table having the eventid means i dont want to select that record (i mean if table 3 have the eventid), else i need to select records
i tried my query
SELECT
*
FROM
`table1` c1
INNER JOIN `table2` c2 ON c2.eventid = c1.eventid
LEFT JOIN table3 c3 ON c3.eventid = c1.eventid
WHERE
c2.zoneid=2
AND c1.active='1'
GROUP BY
c1.eventid

Add a where clause where there is no c3:
SELECT *
FROM `table1` c1
INNER JOIN `table2` c2 ON c2.eventid = c1.eventid
LEFT JOIN table3 c3 ON c3.eventid = c1.eventid
WHERE c2.zoneid=2 AND c1.active='1'
AND c3.id IS NULL
group by c1.eventid

SELECT
*
FROM
`table1` c1
INNER JOIN `table2` c2 ON c2.eventid = c1.eventid
WHERE
c2.zoneid=2
AND c1.active='1'
AND NOT EXISTS (SELECT * FROM table3 c3 WHERE c3.eventid = c1.eventid)
GROUP BY
c1.eventid
Applying a WHERE-condition (like some of the other answers suggest) on a table that has been joined through a LEFT/RIGHT OUTER JOIN will actually make it a regular join.
The other examples that have been posted ask c1.eventid to equal c3.eventid, and c3.eventid to be NULL - good chance that the result will be not what you expect, depending on how the database treats c1.eventid = c3.eventid if both are NULL (I'd have to read up on that).

A Left join on the 3rd table and the condition WHERE C.eventid IS NULL should do the work.
SELECT *
FROM table1 A
INNER JOIN table2 B
ON A.eventid = B.eventid
LEFT OUTER JOIN table3 C
ON A.eventid = C.eventid
WHERE C.eventid IS NULL

Related

Multiple JOINS do not work in a nested JOIN

Why am I unable to join multiple tables?
If I were to run this SQL code without the second INNER JOIN, it works just fine.
SELECT a.name, c1.text, c2.text
FROM `table_a` a
INNER JOIN (
`table_b` b
INNER JOIN `table_c1` c1 ON b.info_id = c1.id
INNER JOIN `table_c2` c2 ON b.info_id = c2.id
) ON a.id = b.person_id;
However, if I add a second JOIN -> INNER JOIN table_c2 c2 ON b.info = c2.id, it ceases to work properly, and won't select anything.
Here is a sqlfiddle for the following problem.
My desired result is that I want it to select from both tables
table_c1 and table_c2.
Here it selects only with table_c1.
SELECT a.name, c1.text
FROM `table_a` a
INNER JOIN (
`table_b` b
INNER JOIN `table_c1` c1 ON b.info_id = c1.id
) ON a.id = b.person_id;
I would want there to be a third row with name "Bob", and text "more_other_table_text"
There are a few things you can do to achieve this:
LEFT JOIN between table_b and c1 & c2.
IFNULL to check for text in c1, otherwise return text from c2.
GROUP BY without an aggregate function to remove the duplicate Sam values from the result set based on the order they were entered into table_2 (you did not specify what value you want when the same person_id is entered multiple times in table_2, if you would like to see both c1 and c2 texts with duplicate names, remove the GROUP BY).
See Fiddle
SELECT a.name, IFNULL(c1.text, c2.text) as `text`
FROM `table_a` a
INNER JOIN (
`table_b` b
LEFT JOIN `table_c1` c1 ON b.info_id = c1.id
LEFT JOIN `table_c2` c2 ON b.info_id = c2.id
) ON a.id = b.person_id
GROUP BY a.name
ORDER BY a.id ASC
The simplest solution is to put your join condition next to the join:
SELECT a.name, b.age, c1.text, c2.text
FROM table_a a
INNER JOIN table_b b ON a.id = b.person_id
INNER JOIN table_c1 c1 ON b.info = c1.id
INNER JOIN table_c2 c2 ON b.info = c2.id
You may also use parentheses, but there is no advantage to doing so:
SELECT a.name, b.age, c1.text, c2.text
FROM table_a a
INNER JOIN (
table_b b
INNER JOIN table_c1 c1 ON b.info = c1.id
INNER JOIN table_c2 c2 ON b.info = c2.id
)
ON a.id = b.person_id

MYSQL - INNER JOIN two tables result TRUE or FALSE

I have a below query that returns a result.
How can query the result which if there is result, return True, and if there is no result, return FALSE??
SELECT a.id
FROM table1 AS a
INNER JOIN table2 AS c
ON (a.id=c.user_id AND a.id=4 AND c.complete_date is NULL AND c.st_number= 8)
You could use EXISTS here:
SELECT EXISTS (
SELECT a.id
FROM table1 AS a
INNER JOIN table2 AS c ON a.id = c.user_id
WHERE a.id = 4 AND c.complete_date IS NULL AND c.st_number = 8
);
Try this,
Please don't merge inner join and where condition
SELECT a.id FROM table1 AS a
INNER JOIN table2 AS c ON a.id=c.user_id
where a.id=4 AND c.complete_date is NULL AND c.st_number= 8

Combining table records

So I have a DB with three tables and negligible knowledge of SQL syntax
Table 1;
person_id;
person_name;
Table 2;
thing_id;
thing_name;
Table 3;
action_id;
action name;
thing_id; (referencing thing_id in the table 2)
person1_id(referencing person_id in the Table 1);
person2_id(referencing person_id in the Table 1);
Basically, I need to combine display 1st person name, 2nd person name, action name and thing name. Could I be directed to some correct join way for this?
Use LEFT JOIN:
select
action_id,
action name,
a1.thing_name,
p1.person_name as person_name1,
p2.person_name as person_name2
from table3
left join table1 p1 on p1.person_id = table3.person1_id
left join table1 p2 on p2.person_id = table3.person2_id
left join table2 a1 on a1.thing_id = table3.thing_id
select t3.action_id,
t3.action_name,
t1.person_name,
t2.person_name
from table3 t3
inner join table2 t2 on t2.ting_id = t3.ting_id,
inner join table1 t1 on t1.person_id = t3.person1_id,
inner join table1 t2 on t2.person_id = t3.person2_id
In SQL SERVER it would be something like this, you might have to adapt it slightly for mysql.
SELECT p1.person_name AS first_person_name, p2.person_name AS second_person_name, t3.action_name, t2.thing_name
FROM
table3 t3
JOIN table1 p1
ON p1.person1_id = t3.person_id
JOIN table1 p2
ON p2.person2_id = t3.person_id
JOIN table2 t2
ON t2.thing_id = t3.thing_id

LEFT JOIN 2 Table but will only return the 1st Record from Table2

table1
cid
itemdesc
itemprice
table2
cid
imagename
status
My 1st table is has unique cid (no duplicate) I want it to LEFT JOIN TO table2 but it has multiple rows per cid
cid imagename status
1 image1-of-cid1 test1
1 image2-of-cid1 test2
2 image1-of-cid2 test3
2 image2-of-cid2 test4
2 image3-of-cid2 test5
But I only want the Query to return the the 1st row only of the each record fom table 1
Thanks
I agree with John Woo's answer above. You need a subquery of some kind to actually retrieve the first row of table 2. Something like:
SELECT
t1.[id],
t2.*
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON t2.cid = (SELECT TOP 1 cid FROM table2 WHERE cid = t1.cid)
you need to create an extra subquery that gets one imagename per cid. try this,
SELECT a.*, b.*
FROM table1 a
LEFT JOIN
(
SELECT cid, MIN(imagename) minImage
FROM table2
GROUP BY cid
) c ON a.cid = c.cid
LEFT JOIN table2 b
ON c.cid = b.cid AND
b.imageName = c.minImage
SQLFiddle Demo
Select
distinct a.cid,a.itemdesc,b.imagename,a.itemprice,b.status
from table1 a,
table2 b
where a.cid=b.cid
Try this:
SELECT a.cid, a.itemdesc, a.itemprice, b.imagename, b.status
FROM table1 a
LEFT OUTER JOIN table2 AS b ON a.cid = b.cid
GROUP BY a.cid, a.itemdesc, a.itemprice;

mySQL: Multi-column join on several tables part II

I am adding a 5th table to an existing join. The original query will always return a single row because the where clause specifies a unique ID. Here are the tables we are using:
Table 1
carid, catid, makeid, modelid, caryear
Table 2
makeid, makename
Table 3
modelid, modelname
Table 4
catid, catname
Table 5
id, caryear, makename, modelname
Here is the existing query I am using:
SELECT a.*, e.citympg, e.hwympg
FROM table1 a
JOIN table2 b on a.makeid=b.makeid
JOIN table3 c on a.modelid=c.modelid
JOIN table4 d on a.catid=d.catid
JOIN table5 e on b.makename = e.make
and c.modelname = e.model
and a.caryear = e.year
WHERE a.carid = $carid;
There are 2 issues that I need to solve -
When there is no match on table 5, it does not return any results. It would seem that I need to do some sort of left join or split the query and do a union.
When there is a match on table 5, it returns multiple rows. Since the criteria that would return a single row is not being used, I would settle for an average of citympg and hwympg.
Can both objectives be achieved with a single query? How?
Assuming I understand what you want correctly... This query will constrain the results from table5 to one row per combination of the join criteria, returning average city/hwy mpg.
SELECT a.*, e.citympg, e.hwympg
FROM table1 a
JOIN table2 b on a.makeid=b.makeid
JOIN table3 c on a.modelid=c.modelid
JOIN table4 d on a.catid=d.catid
LEFT JOIN (SELECT year, make, model,
AVG(citympg) as citympg,
AVG(hwympg) as hwympg
FROM table5
GROUP BY year, make, model) e on b.makename = e.make
and c.modelname = e.model
and a.caryear = e.year
WHERE a.carid = $carid;
Note that it will return NULL mpg values when no record in table5 exists.
The usual approach is to use correlated subqueries like this:
SELECT a.*
, (SELECT avg(e.citympg)
FROM table5 e
WHERE e.make = b.makename
AND e.model = c.modelname
AND e.year = a.caryear
) as citympg
, (SELECT avg(e.hwympg)
FROM table5 e
WHERE e.make = b.makename
AND e.model = c.modelname
AND e.year = a.caryear
) as hwympg
FROM table1 a
JOIN table2 b on a.makeid=b.makeid
JOIN table3 c on a.modelid=c.modelid
JOIN table4 d on a.catid=d.catid
WHERE a.carid = $carid