Left Join to find difference between two tables with different id - mysql

I have two mysql tables: table_old and table_new, both with columns:
name,
surname,
birthdate
birthplace
plus others info columns. Both have an id column that doesn't match between tables. Some records are changed over time between tables, and now I need to have a third table with the records that are changed (added or deleted) between tables.
So I need to compare tables with name and surname and birthdate and birthplace.
I think that I have to use a Left Join, but I'm not sure abut syntax. Any help?

MySQL does not actually support a formal OUTER JOIN operation, but we can simulate one using a union of two joins. Use a full outer join to include records from both tables which do not match to anything in the other table:
SELECT t1.*, 'table one' AS missing
FROM table_old t1
LEFT JOIN table_new t2
ON t1.name = t2.name AND
t1.surname = t2.surname AND
t1.birthdate = t2.birthdate AND
t1.birthplace = t2.birthplace
WHERE t2.name IS NULL
UNION ALL
SELECT t2.*, 'table two'
FROM table_old t1
RIGHT JOIN table_new t2
ON t1.name = t2.name AND
t1.surname = t2.surname AND
t1.birthdate = t2.birthdate AND
t1.birthplace = t2.birthplace
WHERE t1.name IS NULL;
My criteria for claiming that a record is out of date is that any one of the fields does not match. That is, if three fields agree, but one does not, then I do not count it as a match.
Follow the link below for a running demo. You might be able to refine my answer and make it easier to group together pairs of records which are logically the same, but that would take more work.
Demo

Related

LEFT JOIN to show NULL rows + WHERE

I have two tables, one which contains unique names (bill_datatypes), and another one which expresses that these names are connected to some subcategories (one name can be connected to more categories as well).
The first table (relevant part):
The second table (relevant part):
I would like to select all the names which are not connected to a specific subcategory yet. This means that the names might be mentioned in the connecting table but connected to a different subcategory.
I have solved the problem with the following subquery:
SELECT T1.name
FROM bill_datatype T1
WHERE NOT EXISTS (
SELECT T2.bill_datatype_id
FROM obligatory_field T2
WHERE T2.bill_datatype_id = T1.id AND T2.bill_sub_category_id = 1
)
This solution seems to work well, but this way I can not have any data from the second table, which might be needed in the future.
Do you have any suggestions on how to solve the problem with a LEFT JOIN? (The WHERE clause on the subcategory made it too challenging for me.)
Thank you for your help also in advance!
From how I understand your question, I think this query will achieve what you want:
SELECT T1.name
FROM bill_datatype T1
LEFT JOIN obligatory_field T2
ON T2.bill_datatype_id = T1.id AND T2.bill_sub_category_id = 1
WHERE T2.bill_datatype_id IS NULL
The WHERE condition on the JOIN'ed table will give you only the names from T1 which have no bill_sub_category_id or their bill_sub_category_id is not 1.
SQLFiddle
SELECT distinct T1.name
FROM
bill_datatype T1
right join
(
SELECT T2.bill_datatype_id
FROM obligatory_field T2
WHERE T2.bill_sub_category_id = 1
)
as T3
on T1.id != T3.bill_datatype_id
http://sqlfiddle.com/#!9/d4f616/18

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

Join two tables on two columns, even if table 2 does not have row

What I am trying to do is join two tables, lets call them t1 and t2 on two columns. id and name, for this example. t1 will always have id and name, but t2 won't always have id and name. t1 has more columns like viewes, reports, and t2 has other columns that need to be joined. My question is, how can I show 0's for t2's columns if they don't exist?
I hav something similar to this, that joins tables only if both tables' rows have some value.
SELECT
date(t1.start_time) date,
t1.name,
t1.viewes,
t1.reports,
t2.col5,
t2.col6
from
table1 t1
left outer join table2 t2
on t2.name = t1.name and date(t2.start_time) = date(t1.start_time)
group by
1,2
order by
1 desc,
2 asc
;
I have lot's of experience with MySQL, but sometimes find that things need to be hacked to work correctly. What's your suggestion for this problem?

How can we get the value of a column to use as a table name for an inner join?

How can we reference the column value from one table as the reference for a join (see example below)?
SELECT t1.*, t2.*, t3.* FROM term_relationships as t1
INNER JOIN modules as t2 ON t2.module_id = t1.object_id
INNER JOIN t2.nextOfKinTable as t3 ON t3.module_id = t2.module_id;
I thought about using the information_schema but it is too much writing to accomplish something that might be easier by just maintaining a reference to the table you want joined to the current join result, only that I don't know how to make them join this way. Please help :(
Edit:
Essentially what we want is to join table1, table2, and table3 only that the name for table3 is a value stored in table2.
The common column in this case is module_id (object_id)
And the unknown table is t2.nextOfKinTable
Try this out
declare #tabName varchar(1000)
set #tabName = (select top 1 ProductName as tabName from products)
declare #query varchar(8000)
set #query = ' select
p.ProductName as '''+#tabName+'''
from Products p'
---print(#query)
exec (#query)
There's no standard way to do this in SQL. Consider if your t2 table contained 1000 rows, and each row has a distinct nextOfKinTable value. That would result explode the query into a 1002 table join. Not pretty. I'm not even aware of any proprietary syntax that would support it in any products I know of.
If the number of distinct column values are small, you can use LEFT JOINs, but each joined table will receive a different alias (example using 3 tables):
SELECT
t1.*, --TODO: List columns
t2.*, --TODO: List columns
COALESCE(t3.ColumnA,t4.ColumnA,t5.ColumnA) as ColumnA,
COALESCE(t3.ColumnB,t4.ColumnB,t5.ColumnB) as ColumnB
FROM
term_relationships as t1
INNER JOIN
modules as t2
ON
t2.module_id = t1.object_id
LEFT JOIN
Table3 as t3
ON
t3.module_id = t2.module_id AND
t2.nextOfKinTable = 'Table3'
LEFT JOIN
Table4 as t4
ON
t4.module_id = t2.module_id AND
t2.nextOfKinTable = 'Table4'
LEFT JOIN
Table5 as t5
ON
t5.module_id = t2.module_id AND
t2.nextOfKinTable = 'Table5'
You might also want to consider whether these separate tables ought actually to be a single table, with additional column(s) to distinguish the rows. This problem is sometimes referred to as attribute splitting. (See Joe Celko's example of Table splitting in an article from 2009)

MYSQL select query based on another tables entries

I have stumped on this as I am a total beginner in MySql.
Here is a the basic of how the two tables are formed
Table 1
id,product_id, product_name
Table 2
id,product_id,active
Now i know how to do a select statement to query the results from one table but when I have to involve two, I am lost. Not sure if I have to use inner join, left join etc.
So how can I return the results of the product_id from table 1 only if in table 2 is active?
You could use JOIN (as Fosco pointed out), but you can do the same thing in the WHERE clause. I've noticed that it's a bit more intuitive method than JOIN especially for someone who's learning SQL. This query joins the two tables according to product_id and returns those products that are active. I'm assuming "active" is boolean type.
SELECT t1.*
FROM Table1 t1, Table2 t2
WHERE t1.product_id = t2.product_id AND t2.active = TRUE
W3Schools has a good basic level tutorial of different kinds of JOINs. See INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN.
It's pretty simple to join two tables:
select t1.*
from Table1 t1
join Table2 t2 on t1.product_id = t2.product_id
where t2.active = 'Y'