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

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

Related

to fetch data from 2 tables

I am using MySQL to fetch data from 2 tables.
I want to fetch value 116 from column C of table 1 by matching column B of table 1 with column H of table2. If I apply join between the two, I get row second of table 1 as a result. But I want to get value 116 by matching values between the two. How can this be achieved in MySQL?
You seem to want a simple join:
select t2.*, t1.c
from table2 t2 join
table1 t1
on t2.h = t1.b;
You just need to specify the correct columns for lining up the two tables.
INNER JOIN will be good for you, like the following :
SELECT
table2.F as F, table1.A as A, table1.C as C
FROM table2
INNER JOIN table1
ON ( table1.B = table2.H )
or a LEFT JOIN in case C has a null value.
SELECT
table2.F as F, table1.A as A, table1.C as C
FROM table2
LEFT JOIN table1
ON ( table1.B = table2.H )

3 tables and 2 left joins

Query 1:
SELECT sum(total_revenue_usd)
FROM table1 c
WHERE c.irt1_search_campaign_id IN (
SELECT assign_id
FROM table2 ga
LEFT JOIN table3 d
ON d.campaign_id = ga.assign_id
)
Query 2:
SELECT sum(total_revenue_usd)
FROM table1 c
LEFT JOIN table2 ga
ON c.irt1_search_campaign_id = ga.assign_id
LEFT JOIN table3 d
ON d.campaign_id = ga.assign_id
Query 1 gives me the correct result where as I need it in the second style without using 'in'. However Query 2 doesn't give the same result.
How can I change the first query without using 'in' ?
The reason being is that the small query is part of a much larger query, there are other conditions that won't work with 'in'
You could try something along the lines of
SELECT sum(total_revenue_usd)
FROM table1 c
JOIN
(
SELECT DISTINCT ga.assign_id
FROM table2 ga
JOIN table3 d
ON d.campaign_id = ga.assign_id
) x
ON c.irt1_search_campaign_id = x.assign_id
The queries do very different things:
The first query sums the total_revenue_usd from table1 where irt1_search_campaign_id exists in table2 as assign_id. (The outer join to table3 is absolutely unnecessary, by the way, because it doesn't change wether a table2.assign_id exists or not.) As you look for existence in table2, you can of course replace IN with EXISTS.
The second query gets you combinations of table1, table2 and table3. So, in case there are two records in table2 for an entry in table1 and three records in table3 for each of the two table2 records, you will get six records for the one table1 record. Thus you sum its total_revenue_usd sixfold. This is not what you want. Don't join table1 with the other tables.
EDIT: Here is the query using an exists clause. As mentioned, outer joining table3 doesn't alter the results.
Select sum(total_revenue_usd)
from table1 c
where exists
(
select *
from table2 ga
-- left join table3 d on d.campaign_id = ga.assign_id
where ga.assign_id = c.irt1_search_campaign_id
);

MySQL - Join two tables, different columns in table 1 on the same column in table 2

I'm trying to join a different column (part_type_n (where n ranges from 1 to 54)) on Table1 with the same column (id, primary, autoinc) on Table2.
Schema:
Table1
==============
part_type_1
.
.
.
part_type_54
Table2
=============
id
I tried the obvious query (php generated, looping through n from 1 to 54), omitted repetitive stuff in ...:
SELECT * FROM Table1 JOIN Table2 on (Table1.part_type_1=Table2.id), ..., (Table1.part_type_54=Table2.id)
I receive this error:
1066 - Not unique table/alias: 'Table2'
How do I join these two tables?
You will have to join the table on it self again multiple times.
SELECT * FROM table1 t1
INNER JOIN table2 t2 on t2.Id=t1.part_type_1
INNER JOIN table2 t3 on t3.id = t1.part_type_54;
Hope this helps!
As an alternative to writing a query with 54 table aliases, you could consider joining to the table once - like so:
select ...
from Table1 t1
join Table2 t2
on t2.id in (t1.part_type_1, t1.part_type_2, ... t1.part_type_54)
It worked for me to get my required result as one row of which matches various categories all stored in one table column.
Query
SELECT cm3.*, xp.post_title,GROUP_CONCAT(DISTINCT sc.name) AS cate_list
FROM `xld_posts` xp
JOIN course_map cm0 ON cm0.course_id = xp.ID
JOIN course_map cm1 ON cm1.course_id = cm0.course_id AND cm0.id = 3
JOIN course_map cm2 ON cm2.course_id = cm1.course_id AND cm1.id = 6
JOIN course_map cm3 ON cm3.course_id = cm2.course_id AND cm2.id = 11
JOIN subject_category sc ON cm3.id = sc.id
GROUP by post_title ORDER BY post_title
Note: the categories values 3, 6, and 7 are got from form sumbit. Thus if your form has more than three or less your query should dynamically created and join each table with previous table.
:) Happy if any one felt useful.

Linking 3 tables together in MySQL

I'm trying to link 3 database table together through one MySQL request.
Database structure :
Table1 :
table1_id (exemple: 1)
table1_name (exemple: hello world)
Table2 :
table2_id (exemple: empty)
table2_name (exemple: empty)
Table3 :
table3_id (exemple: 1)
table3_name (exemple: random_name
MySQL Request
SELECT * FROM table1 AS a, table2 AS b, table3 AS c
WHERE a.table1_id = b.table2_id
AND a.table1_id = c.table3_id AND table3_name = "random-name"
Problem
The previous request won't display any result because table2 is empty. Do you have an idea how I could get the data coming from table 1 & 2, letting table3's fields empty without using two requests ?
You should change your request to use a LEFT JOIN instead of an INNER JOIN:
select *
from table1 t1
left join table2 t2
on t1.table1_id = t2.table2_id
left join table3 t3
on t1.table1_id = t3.table2_id
and t3.table3_name = 'random-name'
The INNER JOIN produces a set of data if the id exists in all tables. The LEFT JOIN will return records from table1 even if there are no records in table2 or table3.
If you need help learning about join syntax, here is a great visual explanation of joins
Couple thoughts:
Don't use SELECT *, name the columns explicitly
Don't use implicit join syntax; use ON clauses
To preserve rows that do not "match" on a join condition, use a LEFT OUTER JOIN
Therefore, try this:
SELECT a.table1_id, a.table1_name
, b.table2_id, b.table2_name
, c.table3_id, c.table3_name
FROM table1 AS a
LEFT OUTER JOIN table2 AS b
ON b.table2_id = a.table1_id
JOIN table3 AS c
ON c.table3_id = a.table1_id
WHERE c.table3_name = "random-name"

Multiple INNER JOIN returns null

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