MySQL JOIN from one of the two table based on IF condition - mysql

SELECT Table1.Filter, Table1.Condition, Combined.Data FROM Table1
LEFT JOIN
(SELECT Key, Data FROM IF(Table1.Filter, Table2, Table3))) AS Combined
ON Table1.Condition = Combined.Key
I want to create a MySQL View that shows all columns of Table1, and a column from either Table2 or Table3 depending on the field on Table1.Filter.
One simple solution is to LEFT JOIN both Table2 and Table3, with NULL on the column that is not applicable. Is there a way to avoid creating 2 columns?
I cannot UNION Table2 and Table3 as they might contain the same Key.

The following should do what you want:
SELECT t1.Filter, t1.Condition,
COALESCE(t2.Data, t3.Data) as Data
FROM Table1 t1 LEFT JOIN
Table2 t2
ON t1.Filter AND t2.Key = t1.Condition LEFT JOIN
Table3 t3
ON (NOT t1.Filter) AND t3.key = t1.condition;
You cannot have conditionals choosing tables in the FROM. But, you can have conditions in the ON conditions.

Related

Guide to break this Sql code in subprocesses

I have a sql query which reads as below
select *
FROM Table1
LEFT JOIN Table2
ON Table1.id =
Table2.action_id
LEFT JOIN Table3
ON Table1.changeset_id =
Table3.id
LEFT JOIN Table4
ON Table2.field_id =
table4.id
I seek help to understand what will be going to happen in this code after completion. I understand the first part i.e.
select *
FROM Table1
LEFT JOIN Table2
ON Table1.id =
Table2.action_id
This I understand as join Table1 and Table2 based on id (Table1) and action.id(Table2) and after joining consider only those rows which have entries in id(Table1) by means of LEFT JOIN.
But then am lost. What is the significance of next two LEFT JOIN?
How can I properly break this entire code into sub-processes to understand flow of execution process? Apology if my question is too trivial
You have a series of LEFT JOINs:
FROM Table1 LEFT JOIN
Table2
ON Table1.id = Table2.action_id LEFT JOIN
Table3
ON Table1.changeset_id = Table3.id LEFT JOIN
Table4
ON Table2.field_id = table4.id
What this does is keep all rows in Table1, regardless of the matches in the subsequent tables.
Which rows match then follows the ON conditions. This is simple if they only refer to the first table and the given table. In your case, they also refer to intermediate tables.
So:
For Table2 you get columns for all rows that match Table1
For Table3 you get columns for all rows that match Table1
For Table4 you get columns for all rows in Table4 that match rows in Table2 that match rows in Table1.
I find that this is a little more complicated to explain than understand. The key is that NULL values (which are missing values in outer joins) do not match the ON conditions.
LEFT JOIN Table3 ON Table1.changeset_id = Table3.id will add data for each row from Table3 only if Table1.changeset_id exists in Table3.id.
LEFT JOIN Table4 ON Table2.field_id = table4.id will add data for each row from Table4 only if Table2.field_id exists in Table4.id. If there is no match in the Table2 LEFT JOIN, you can be sure there is no match for this JOIN too.
When the left join can not be resolved, you will have all the column of the table with NULL value.
Did I understand the question correctly or was there something more complex?

Joining multiple columns in table1 with multiple columns in table2 with additional condition MySql

I have table_1 with unique records of IDs and multiple columns of data
and
table_2 with multiple rows concerning particular ID and multiple columns. One of the column in table2 is, say, time_lapse.
I need those two tables joined with all columns saved but with only those rows from table2 with highest time_lapse value.
I was trying this way...
create table as new_table
select table1.*, table2.* from
table1 left join table2
on table1.id=table2.id
where time_lapse=
(select max(time_lapse) from table2
group by id);
... but it failed.
Any suggestions for a newbie? Thank you.
You are close. But you are selecting the maximum time_lapse per id and then you act as if you had only selected one record with only one time_lapse. Use IN and have the id in the select list of your subquery:
create table as new_table
select table1.*, table2.* from
table1 left join table2
on table1.id=table2.id
where (table2.id, table2.time_lapse) in
(select id, max(time_lapse) from table2
group by id);
Then you are outer-joining table2, but want certain criteria on it in the WHERE clause. That doesn't work (as columns in outer-joined records are null).
The same query a tad prettier with a real outer join:
create table as new_table
select t1.*, t2.*
from table1 t1
left join table2 t2 on t1.id = t2.id
and (t2.id, t2.time_lapse) in
(select id, max(time_lapse) from table2 group by id);

Mysql need to get one column two times from table1 and sort them by two different columns of table2

So here is the thing, I have two tables:
table1 has columns intUsersID, varUsersName
table2 has columns intCouriers, intResponsible
intCouriers (have some numbers of intUsersID that are Couriers), and intResponsible (have some numbers of intUsersID that are Responsible)
In my query I must see User Names of Couriers and of the Responsible persons
something like that:
SELECT
table1.varUsersName 'Couriers',
table1.varUsersName 'Responsible'
FROM
table1
LEFT JOIN
table2 ON table2.intCouriers = table1.intUsersID
And then I need some how to subquery or join this "table1.varUsersName 'Responsible'", to get also 'Reponsible' persons. Please help me.
Should be this
SELECT table1.varUsersName 'Couriers', table2.varUsersName 'Responsible'
FROM table1
INNER JOIN table3 on table1.intUsersID = table3.intCouriers
INNER JOIN table1 as Table2 on table2.intUsersID = table3. intResponsible
SELECT Couriers.varUsersName as "Couriers",
Responsible.varUsersName as "Responsible"
FROM `table2` t2
LEFT JOIN table1 Couriers on Couriers.intUsersID = t2.intCouriers
LEFT JOIN table1 Responsible on Responsible.intUsersID = t2.intResponsible

How to combine 2 columns from 2 tables and subtract duplicates

I have 2 tables t1 and t2. Each have a customer ID column. What I am looking for is to join the 2 columns and SUBTRACT the duplicates.
My EG:
Table1 and Table2 with the IDs for each
I have tried a union query. The result I am left with is ID = 1,2,3,4,5,6,7,8,9,10. Where, what I'm after is subtracting 1-5 from Table2 and the result = 6,7,8,9,10.
I hope that makes sense and that someone is able to help. Sorry if this is a bit too simple compared to what you're all used to.
In SQL Server you can use the EXCEPT operator:
select ID
from Table2
except
select ID
from Table1
Mysql does not support it though. Using a an in clause or a left join would work in both servers:
--Using In clause
SELECT ID
FROM Table2
WHERE ID NOT IN
(
SELECT ID
FROM Table1
);
--Using join
SELECT Table2.ID
FROM Table2
left join Table1
on Table2.ID = Table1.ID
where Table1.ID is null
Use left outer join
select * from t1 left outer join t2 on t1.customerid = t2.customerid

LEFT JOIN or INNER JOIN to find items from one table that are in second table

I have a quick question on JOINS.
If I wanted to find how many items from table1 that are used in table2, would I use a INNER JOIN or LEFT JOIN (se below).
An INNER JOIN would show me where 'ID' is in both tables so should represent when ID from table1 is used in table2, but then listing all table2 where ID is the same as table1 ID (LEFT JOIN) should bring back the same?
But the results are different:
INNER JOIN brings back 252,222
LEFT JOIN brings back 258,637
PS: table2 is a child of table1, so table2 IDs can only be from table1 (table1 a list of products, table2 a list of selected products) so looking for all products from table1 that are seleted so in table2 (been selected)
SELECT DISTINCT
t1.name, t1.details
FROM
table1 AS t1
INNER JOIN
table2 AS t2 ON t1.id = t2.t1_id
SELECT DISTINCT
t1.name, t1.details
FROM
table1 AS t1
LEFT JOIN
table2 AS t2 ON t1.id = t2.t1_id
Which would br the correct SQL, I'm guessing INNER JOIN.
LEFT JOIN is not the same as INNER JOIN. With a LEFT JOIN, those rows are returned too, that are not present in the second table! If you want those records, that have their IDs in the second table too, use INNER JOIN.
An INNER JOIN would show me where 'ID' is in both tables so should represent when ID from table1 is used in table2, but then listing all table2 where ID is the same as table1 ID (LEFT JOIN) should bring back the same?
In this case, an INNER JOIN makes perfect sense as it would give records common to both table1 and table2.
table2 is a child of table1, so table2 IDs can only be from table1 (table1 a list of products, table2 a list of selected products) so looking for all products from table1 that are seleted so in table2 (been selected)
This requires you to enforce FOREIGN KEY constraint in TABLE2 that IDs can only be present after they are present in TABLE1. Once you do this, then it makes sense.
For left join if the result is not satisfied joined then the result is returned from table1 and table2 null of.
In the case of inner join will return only results that satisfy the condition.