How to select two seperate non-overlapping tables in MySQL - mysql

I'm looking for a query to select rows from two different tables, keeping the column names the same (I did find one result here for selecting from two different tables, but it merged the column names to have an easier query). I need to keep the original column names, but have two different tables existing within the new, larger table. There are no overlapping columns between the two tables.
A picture, to visualise:
So, how can I do this? I know the query will probably be quite convoluted, but anything half-decent is probably going to be better than my current attempt:
SELECT t1.* , t2.*
FROM table1 t1 RIGHT OUTER JOIN table2 t2
ON r.someColumn1 = rc.someColumn2
UNION
SELECT t1.* , t2.*
FROM table1 t1 LEFT OUTER JOIN table2 t2
ON r.someColumn1 = rc.someColumn2
This does work, but only as long as there are no cases where someColumn1 = someColumn2 - which can happen quite easily, of course.
Any help is appreciated, and I apologise for what is probably a very silly question to which the smart answer is "don't do it, you fool!".

You can set your join criterion to never match:
SELECT t1.* , t2.*
FROM table1 t1 RIGHT OUTER JOIN table2 t2
ON 1 = 0
UNION
SELECT t1.* , t2.*
FROM table1 t1 LEFT OUTER JOIN table2 t2
ON 1 = 0
I don't have MySQL to test, but it works in SQL Server.

Edit: my first answer was wrong:
select * from Events
left join GroupList on ID=null
union
select Events.*,GroupList.* from GroupList
left join Events on GID=null
In the above GID and ID are keyfields in the tables.

Related

Full Outer Join get repeated with Union?

I'm trying to accomplish a Full Outer Join with my SQL.
Reference Link
FULL (OUTER) JOIN: Return all records when there is a match in
either left or right table
Although apparently this is not supported. I've looked around and have come across this accepted answer: https://stackoverflow.com/a/4796911/3859456
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
Although won't this at least repeat the matched records twice when we do a Union? If not does a union automatically overwrite the matched records to the 2 tables?
E.g.
LEFT (OUTER) JOIN: Return all records from the left table, and the
matched records from the right table
RIGHT (OUTER) JOIN: Return all
records from the right table, and the matched records from the left
table
Union Left-Outer-Table + (left-matched = right-matched)x2 + Right-Outer-Table
I'm sure the answer works as the community trust it. But I'm still confused as to how it works and hope that someone can help me understand better.
To reiterate from the accepted answer to which you refer, I will quote both the UNION and UNION ALL versions:
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
and
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION ALL
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
WHERE t1.id IS NULL
If there were no duplicates generated by the join, then these two queries would return the same result set. The reason can be explained as:
The first half of the UNION/UNION ALL returns all records in common between the two tables (no duplicates, by our assumption), and it also return those records unique to the first table t1.
The second half of the union query returns all records in common and all records unique to the second table t2. But the UNION filters out those duplicate common records without altering the result set, since we assumed there are no duplicates.
The second half of the union all query selectively removes the duplicate common records using WHERE t1.id IS NULL. This ensures that only the records unique to the second table are added by the second half of the UNION ALL.
Now, if the first table itself happened to have duplicates, this is what would happen:
In the union query, duplicate records which occurred in the first table would be filtered off. This is subtle, because duplicates can arise from two sources here. First, there could be duplicates with the first table itself. Second, there could be duplicates which arise from the join. All duplicates would be removed from a UNION.
However, in the union all query, no duplicates would be removed. The duplicate records which might happen to appear in the first table would survive intact in the final result set, as would any duplicates which resulted from the join.
This is a long winded answer, but hopefully it convinces you that in the case of duplicates, the UNION and UNION ALL versions of the accepted answer may not generate the same result set.

Select everything from joined tables

I have two joined tables:
SELECT table1.*, table2.* FROM table1 t1 INNER JOIN table2 t2 ON t1.id = t2.t1_id
The question: In query results, id will always be taken from secondary table defined in SELECT statement?
For example:
if I use select t1.*, t2.* - in results id will be t2.id
if I use select t2.*, t1.* - id will be t1.id.
Is this good practice to use 'merged' result, or should I avoid ambiguity, and always define columns strictly?
No, the sql query will return all columns with the same name from all tables, not just the last one, unless you use a natural join (table1 inner join table2 using(column)).
If you use some kind of a component that stores the results in associative arrays, then these components usually use only the field names as key, therefore they return only the last column's value from those that have the same name.
However, it is a good practive to use an alias if you want to return more than 1 column that has the same name in the database.
My suggestion is to use tablename with alias and get to use like this. It would be best practice to run query.Mention your column names even though it has many columns. You can order your display.
SELECT t1.columnName1, t2.columnName2 FROM tablename1 t1 INNER JOIN tablename2 t2 ON t1.id = t2.id

sql query building with query data

I have to tables who looks like this
Table1
User_ID(int)|comment(text)|gender(int)
so it could be like 1|bla bla|1
Table2
ID(int)|Username(text)
Now I want to build a query like
SELECT Table1.User_ID,Table1.comment,Table1.gender FROM Table1 INNER JOIN Table2 ON Table1.User_ID=Table2.ID SELECT Username
Is something like that working? I hope my query is not that bad to understand. If thats working in one way or another, is it also possible to make some more joins?
First time I have to work with joins. I'm a bit irritated, most examples are a bit abstract,..
Just list every columns that you want to select after the SELECT statement, even if they come from joined tables.
SELECT Table1.User_ID, Table1.comment, Table1.gender, Table2.Username
FROM Table1 INNER JOIN Table2
ON Table1.User_ID = Table2.ID
You could have as many joins as you want:
SELECT Table1.User_ID, Table1.comment, Table1.gender, Table2.Username
FROM Table1
INNER JOIN Table2
ON Table1.User_ID = Table2.ID
INNER JOIN Gender
ON Table1.gender = Gender.id
Yes and yes. You can access table 2 fields in select statement also.

MySQL LEFT JOIN in CASE?

I have a table where I want to join different tables depending on the value of one column, like so (this doesn't work, but it's my example):
SELECT * FROM table1
JOIN (CASE WHEN table1_column1=1 THEN table2 ON table2_column1=table1_column2 END)
WHERE table1_column3='hello'
All in all there are gonna be 4 values in the column, calling other tables. Is this doable?
Edit: I think I need to clarify what I'm after. Depending on the value of table1_column1, I want the JOIN to fetch a specific table and column. For example, if t1c1=1 it should join table2_column1 on table1_column2. If, however, t1c1=2 it should join table5_column1 on table1_column2. Etc, etc, etc.
Again - is this doable? It's easily scripted if I use two separate queries. I just want to use one query, however.
SELECT * FROM
table1 JOIN table2 ON table2_column1=table1_column2 AND table1_column1=1
UNION
SELECT * FROM
table1 JOIN table3 ON table2_column1=table1_column2 AND table1_column3='hello'
it might work
SELECT * FROM table1
JOIN table2 ON table2_column1=table1_column2 and table1_column1=1
WHERE table1_column3='hello'

How to retrieve non-matching results in mysql

I'm sure this is straight-forward, but how do I write a query in mysql that joins two tables and then returns only those records from the first table that don't match. I want it to be something like:
Select tid from table1 inner join table2 on table2.tid = table1.tid where table1.tid != table2.tid;
but this doesn't seem to make alot of sense!
You can use a left outer join to accomplish this:
select
t1.tid
from
table1 t1
left outer join table2 t2 on
t1.tid = t2.tid
where
t2.tid is null
What this does is it takes your first table (table1), joins it with your second table (table2), and fills in null for the table2 columns in any row in table1 that doesn't match a row in table2. Then, it filters that out by selecting only the table1 rows where no match could be found.
Alternatively, you can also use not exists:
select
t1.tid
from
table1 t1
where
not exists (select 1 from table2 t2 where t2.tid = t1.tid)
This performs a left semi join, and will essentially do the same thing that the left outer join does. Depending on your indexes, one may be faster than the other, but both are viable options. MySQL has some good documentation on optimizing the joins, so you should check that out..