MySQL Join Query for With Multiple Columns - mysql

I have a question that I think is simple enough but I seem to be having some trouble with it.
I have two tables. Each table has the exact same rows.
I am trying to perform a join on the two tables with the following query:
SELECT t1.`* FROM `person` as t1
JOIN `person_temp` as t2
on t1.`date` = t2.`date`
and t1.`name` = t2.`name`
and t1.`country_id`= t2.`country_id`
The point of this query is to find all of the rows in t1 that match t2 where the combination of date,name, and country_id are the same (those three columns combined make a record unique). i don't think this query is correct for what I am trying to do because if I have the same exact data in both tables I am getting a much larger number of matches back.
Any ideas on how to edit this query to accomplish what I am trying to do?

Don't use join. Use exists:
SELECT t1.`*
FROM `person` t1
where exists (select 1
from `person_temp` as t2
where t1.`date` = t2.`date`
and t1.`name` = t2.`name`
and t1.`country_id`= t2.`country_id`
);
For performance, you want a composite index on person_temp(date, name, country_id) (the columns can be in any order).

Related

How to delete duplicate data based on two columns

I want to make a query that deletes duplicate data leaving only one duplicate data when two columns overlap.
Maybe because of a lot of data, but the following query doesn't work for a long time
DELETE t1 FROM table t1 INNER JOIN table t2
WHERE t1.idx < t2.idx AND t1.Nm = t2.Nm AND t1.product = t2.product;
Can this query do what I want? If not, what is the other way?
Create an Index on the 3 columns involved in the ON clause:
CREATE INDEX idx_name
ON tablename (Nm, product, idx);
and execute the query like this:
DELETE t1 FROM tablename t1 INNER JOIN tablename t2
WHERE t1.Nm = t2.Nm AND t1.product = t2.product AND t1.idx < t2.idx;
As you can see in this simplified demo, the query will be executed using the index.

MySQL Joins of tables with different columns

I want to create a table that needs to be a combination of selected columns from three or more tables. I don't have any sample data, just added the columns for explanation.
Table 1
A|B1|C1|D1|E1|F1|G1|H1|I1|J1
Table 2
A|B2|C2|D2|E2|F2|G2
Table 3
A|B3|C3|D3|E3|F3|G3
Resultant New table must have
A|B1|E1|F1|G1|J1|C2|D2|G2|B3|D3|F3
I'm not sure if I need to use a FULL JOIN or use UNIONS.
Each of these tables contain more than 400,000 rows. Any help here on what query needs to be included would be really helpful.
You can try the below query:
select t1.A,t1.B1,t3.E1,t1.F1,t1.G1,t1.J1,t2.C2,t2.D2,t2.G2,t3.B3,t3.D3,t3.F3
from table1 t1 join table2 t2 on t1.A = t2.A
join table3 t3 join table2 t2 on t3.A = t2.A
As Palec commented correctly in the other answer, so adding a bit of explanation to the answer.
You need to use the JOINS for this problem instead of UNION. The reason why I am saying to use JOINS over UNION is UNION combines the data/result of two or more queries into a single result set which includes all the rows which exist in the queries in your UNION. But when you are using JOINs, you can retrieve data from two or more tables based on logical relationships between the tables.
Also to add that you should add an alias name to your table so that it becomes easy to retrieve the column in the select query and also while linking the table.
Join is the correct way:
select table1.A,B1,E1,F1,G1,J1,C2,D2,G2,B3,D3,F3 from table1 join table2 on table1.A = table2.A
join table3 join table2 on table3.A = table2.A

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?

Create a VIEW where a record in t1 is not present in t2 ? Confirmation on Union/Left Join/Inner Join?

I am trying to make a view of records in t1 where the source id from t1 is not in t2.
Like... "what records are not present in the other table?"
Do I need to include t2 in the FROM clause? Thanks
SELECT t1.fee_source_id, t1.company_name, t1.document
FROM t1
WHERE t1.fee_source_id NOT IN (
SELECT t1.fee_source_id
FROM t1 INNER JOIN t2 ON t1.fee_source_id = t2.fee_source
)
ORDER BY t1.aif_id DESC
You're looking to effect an anti-join, for which there are three possibilities in MySQL:
Using IN:
SELECT fee_source_id, company_name, document
FROM t1
WHERE fee_source_id NOT IN (SELECT fee_source FROM t2)
ORDER BY aif_id DESC
Using EXISTS:
SELECT fee_source_id, company_name, document
FROM t1
WHERE NOT EXISTS (
SELECT * FROM t2 WHERE t2.fee_source = t1.fee_source_id LIMIT 1
)
ORDER BY aif_id DESC
Using JOIN:
SELECT t1.fee_source_id, t1.company_name, t1.document
FROM t1 LEFT JOIN t2 ON t2.fee_source = t1.fee_source_id
WHERE t2.fee_source IS NULL
ORDER BY t1.aif_id DESC
According to #Quassnoi's analysis:
Summary
MySQL can optimize all three methods to do a sort of NESTED LOOPS ANTI JOIN.
It will take each value from t_left and look it up in the index on t_right.value. In case of an index hit or an index miss, the corresponding predicate will immediately return FALSE or TRUE, respectively, and the decision to return the row from t_left or not will be made immediately without examining other rows in t_right.
However, these three methods generate three different plans which are executed by three different pieces of code. The code that executes EXISTS predicate is about 30% less efficient than those that execute index_subquery and LEFT JOIN optimized to use Not exists method.
That’s why the best way to search for missing values in MySQL is using a LEFT JOIN / IS NULL or NOT IN rather than NOT EXISTS.
However, I'm not entirely sure how this analysis reconciles with the MySQL manual section on Optimizing Subqueries with EXISTS Strategy which (to my reading) suggests that the second approach above should be more efficient than the first.
Another option below (similar to anti-join)... Great answer above though. Thanks!
SELECT D1.deptno, D1.dname
FROM dept D1
MINUS
SELECT D2.deptno, D2.dname
FROM dept D2, emp E2
WHERE D2.deptno = E2.deptno
ORDER BY 1;

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'