Multiple INNER JOIN returns null - mysql

I'm working on joining 3 tables.
table1.
grp_id | email_id
1 | 3
1 | 58
table2.
sam_msg_id | sam_subject
3 | Funnel
table3.
id | subject
58 | testing check
Desired Output:
id |grp_id|email_id|sam_subject|subject |
184|1 |3 |funnel | |
185|1 |58 | |testing check|
the query I tried:
SELECT table1.*, table2.sam_subject, table3.*
FROM table1
INNER JOIN table2
ON table2.sam_msg_id = table1.email_id
INNER JOIN table3
ON table3.id = table1.email_id
WHERE table1.grp_id = '1'
What I'm trying to do here is to get the list of subject and its id from table2 and table3 where the id is found at table1 under email_id.
When I tried doing it with one inner join only by checking only the data from table2 it was working.
I am not familiar in using inner joins thus I can't really see what I'm doing wrong.
I am using MySQL.

Sounds like you need a LEFT JOIN
SELECT table1.*, table2.sam_subject, table3.*
FROM table1
LEFT JOIN table2
ON table2.sam_msg_id = table1.email_id
LEFT JOIN table3
ON table3.id = table1.email_id
WHERE table1.grp_id = '1'
Based on you edit, the following should give you the results you want:
SELECT t1.grp_id,
t1.email_id,
coalesce(t2.sam_subject, '') sam_subject,
coalesce(t3.subject, '') subject
FROM t1
left JOIN t2
ON t2.sam_msg_id = t1.email_id
left JOIN t3
ON t1.email_id = t3.id
WHERE t1.grp_id = '1'
See SQL Fiddle with Demo

I'm a bit confused about what you are asking. If you can provide an example of your current data and your desired output we can probably nail down a solution.
As it is, I suspect you need to read up on LEFT JOIN, which will return NULL if there is no matching record in your child table. INNER JOIN will not return a record if there is no match.
Take a look at this article for an explanation of the different types of joins:
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
UPDATE:
I'm not sure where the first column of your desired results is coming form but the query below should get you the desired results:
SELECT t1.*, t2.sam_subject, t3.subject
FROM Table1 as t1
LEFT JOIN table2 as t2
on t1.email_id = t2.sam_msg_id
LEFT JOIN table3 as t3
on t1.email_id = t3.id

Related

Join two tables... without JOIN

I've got two tables T1 and T2, both with a single field (id).
T1.id has values:
1
2
4
T2.id has values:
1
3
4
I need to join these tables.
Desired result:
T1 | T2
------|------
1 | 1
2 | null
null | 3
4 | 4
With JOIN I'd do it easily:
Query 1
SELECT * FROM T1 FULL JOIN T2 ON T1.id=T2.id
But due to certain reasons I can't use JOIN here. So, with a simple query like this
Query 2
SELECT * FROM T1, T2 WHERE T1.id=T2.id
I would get only two rows of data
T1 | T2
------|------
1 | 1
4 | 4
as two other rows would be omitted due to no matches in the other table.
No matter what to fill the missing matches with. It could be NULL or any other value - really anything, but I need to get those omitted rows.
Is there a way to modify Query 2 to get the desired result without using any JOIN?
PS: Real tables are different in structure, so UNION is not allowed either.
PPS: I've just given a model to point out the problem. In reality it's a "megaquery" involving many tables each having dozens of columns.
Standard way to implement FULL OUTER JOIN when only implicit joins are supported.
select t1.id t1id, t2.id t2id
from t1, t2 where t1.id = t2.id
union all
select id, null from t1
where not exists (select 1 from t2 where t2.id = t1.id)
union all
select null, id from t2
where not exists (select 1 from t1 where t1.id = t2.id)
order by coalesce(t1id, t2id)
The first SELECT produces the INNER JOIN part of the result.
The second SELECT adds the additional LEFT OUTER JOIN rows to the result.
The third SELECT adds the additional RIGHT OUTER JOIN rows to the result.
All together, a FULL OUTER JOIN is performed!
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=ec154ad243efdff2162816205fdd42b5
SELECT t1.id t1_id, t2.id t2_id
FROM ( SELECT id FROM table1
UNION DISTINCT
SELECT id FROM table2 ) t0
NATURAL LEFT JOIN table1 t1
NATURAL LEFT JOIN table2 t2

MySQL: Get data from multiple tables allowing nulls with a list of ids

I got this tables that look like this:
table 1
|id|value1|value2|value3
table 2
|id|value4|value5|value6
The id value in each table is unique but an id could appear in a table 1 but no in table 2. (value 1 is equal to value4 but if id dont appear in table 2 value4 would be null... )
Then I got this a of ids and I want to get sometime like (supossing that id appear in table 1 but no in 2 and vice versa):
resultgrid
| id | value1| value2| value3|value4|value5|value6
|838383|result1|result2|result3|null |null |null
|548438|null |null |null |result4|result5|result6
hope you guys can help me, thanks!
EDIT: query i've been trying (it's actually a set of collected pieces of answer i'd see in stack overflow)
SELECT t1.*, t2.value4, t2.value5, t2.value6
FROM table1 as t1
JOIN table2 AS t2 ON t2.id = t1.id
Where t1.id = t2.id = 838383
this get me 0 rows returned.
I want to make it general to use the <2000 id list.
You want a full outer join which MySQL does not support. In your case, you can emulate this with left join:
select t1.*, t2.value4, t2.value5, t2.value6
from (select 838383 as id
) i left join
table1 t1
on t1.id = i.id left join
table2 t2
on t2.id = i.id;
The list of ids you want to keep goes in the i subquery.
You can use two different Select queries, using Left join between the two tables. In the first query, consider table1 as leftmost table; and table2 as leftmost in the second query.
Use Where <right table id> IS NULL to filter out rows where there is no matching entry in the rightmost table.
Use Union to combine the resultset. Since there will not be any duplicates (due to our query results), we can use Union All.
Try the following:
SELECT t1.id, t1.value1, t1.value2, t1.value3,
t2.value4, t2.value5, t2.value6
FROM table1 AS t1
LEFT JOIN table2 AS t2 ON t2.id = t1.id
WHERE t2.id IS NULL
UNION ALL
SELECT t2.id, t1.value1, t1.value2, t1.value3,
t2.value4, t2.value5, t2.value6
FROM table2 AS t2
LEFT JOIN table1 AS t1 ON t1.id = t2.id
WHERE t1.id IS NULL

Mysql Inner join with concat_ws

I have 2 table.
first table
| idgroup | namegroup
second table
| idrequest | col1 | col2 | N1 | N2 | date_extract |
I want to join the tables with concat_ws
SELECT
tb1.*,tb2.*,
CONCAT_WS("_",tb2.N1, tb2.N2) AS GR,
FROM
table2 tb2
INNER JOIN table1 tb1 ON tb1.namegroup= tb2.GR
WHERE
tb2.date_extract = "2015-02-13"
Is it possible? then how?
I am giving a blind try. Nothing changed much except a date() conversion to tb2.date_extract-taking the date value if date_extract is of type TIMESTAMP or DATETIME.
SELECT
tb1.*,tb2.*,
CONCAT_WS("_",tb2.`N1`, tb2.`N2`) AS `GR`,
FROM
table2 tb2
INNER JOIN table1 tb1 ON tb1.`namegroup`= tb2.GR
WHERE
date(tb2.`date_extract`) = "2015-02-13"
If this is not your problem, then please post the error message with the question.
UPDATE: You can simply use GR instead of tbl2.GR need to use the namespace for the result
SELECT
tb1.*, tb2.*, CONCAT_WS("_",tb2.`N1`, tb2.`N2`) AS `GR`,
FROM table2 tb2
INNER JOIN table1 tb1 ON tb1.`namegroup`= `GR`
WHERE
date(tb2.`date_extract`) = "2015-02-13"
-now let me know how it goes?

how to make query show the an other column of the primary key?

umm I'm not sure I've made the title right but its kind of hard to express it in short words.
I have to tables
table1:
id | name
1 | alice
2 | bob
table 2:
user_id | date
2 | 2014-11-1
2 | 2014-11-2
1 | 2014-11-3
as a query, if I want to show table 2 but instead of the integer numbers of user_id, I want it to show the corresponding names of the users where this info is stored in table 1.
I think this is supposed to be easy but I don't know how to get this done.
A query along the lines of -
select t1.name, t2.date
from table_1 t1 inner join table_2 t2 on t1.id = t2.user_id
Try:
SELECT t2.user_id, t1.name
FROM table1 t1 INNER JOIN table2 t2
ON t1.id = t2.user_id
This will do it.
SELECT
`b`.`name`,
`a`.`date`
FROM
table2 a
INNER JOIN table1 b ON (a.user_id = b.id)
SELECT
B.[Name]
,A.[date]
FROM [table 2] A
LEFT OUTER JOIN [table1] B
ON A.[user_id] = B.[id]

MySQL: Joining different tables based on an if/case statement

I have a table with two sets of IDs (dec_id and rec_id). If dec_id is found in Table1, I need to left join that table. If not - left join table2. The same goes for the second column. I also need to know which ID was found in which table.
Here's the abstract structure of Table 1:
dec_id rec_id
-----------------
11 16
23 24
15 31
Tables 2 and 3 are for all intends and purposes identical (apart from the actual data):
id name data1 data2
------------------------------------------
11 a x p
41 b y q
55 c z r
And the logic (abstract):
IF (dec_id IS IN Table1) {
LEFT JOIN Table1 on (dec_id = table1.id);
LEFT JOIN Table2 on (rec_id = table2.id);
FLAG = 1;
} ELSE {
LEFT JOIN Table1 on (rec_id = table1.id);
LEFT JOIN Table2 on (dec_id = table2.id);
FLAG = 0;
}
LEFT JOIN Table3, Table4, ...
I know the result can be achieved in PHP with more than one query, but I'd like to avoid it if possible for the sake of efficiency; unfortunately my SQL knowledge fails me.
Thanks in advance!
Are you looking for something like this?
SELECT COALESCE(t2.id, t3.id) id,
(t2.id IS NOT NULL) flag,
COALESCE(t2.name, t3.name) name,
COALESCE(t2.data1, t3.data1) data1
FROM table1 t1 LEFT JOIN table2 t2
ON t1.dec_id = t2.id LEFT JOIN table3 t3
ON t1.rec_id = t3.id
Here is SQLFiddle demo