How do i compare 2 fields in 2 tables, find a match and use it ?
example:
table1: data1(id_data1,name,address,phone,account)
table2: data2(id_data2,name2)
now in php:
if (name2.table2 has a matching name in name.table1) { give me the address,phone,account }
I suppose you want to use JOINs
SELECT data FROM table1 INNER JOIN table2 ON table1.id=table2.id
There are different types of JOINs, which one to use will depend on what you need.
Here's a question on visualizing the different types of JOINs.
EDIT: I believe you are looking for something like this:
SELECT table1.name, phone, other_info_here
FROM table1 AS t1 RIGHT JOIN table2 AS t2 ON t1.name=t2.name
WHERE t1.name IS NOT NULL
Related
table1 (id, name)
table2 (id, name)
Query:
SELECT name
FROM table2
-- that are not in table1 already
SELECT t1.name
FROM table1 t1
LEFT JOIN table2 t2 ON t2.name = t1.name
WHERE t2.name IS NULL
Q: What is happening here?
A: Conceptually, we select all rows from table1 and for each row we attempt to find a row in table2 with the same value for the name column. If there is no such row, we just leave the table2 portion of our result empty for that row. Then we constrain our selection by picking only those rows in the result where the matching row does not exist. Finally, We ignore all fields from our result except for the name column (the one we are sure that exists, from table1).
While it may not be the most performant method possible in all cases, it should work in basically every database engine ever that attempts to implement ANSI 92 SQL
You can either do
SELECT name
FROM table2
WHERE name NOT IN
(SELECT name
FROM table1)
or
SELECT name
FROM table2
WHERE NOT EXISTS
(SELECT *
FROM table1
WHERE table1.name = table2.name)
See this question for 3 techniques to accomplish this
I don't have enough rep points to vote up froadie's answer. But I have to disagree with the comments on Kris's answer. The following answer:
SELECT name
FROM table2
WHERE name NOT IN
(SELECT name
FROM table1)
Is FAR more efficient in practice. I don't know why, but I'm running it against 800k+ records and the difference is tremendous with the advantage given to the 2nd answer posted above. Just my $0.02.
SELECT <column_list>
FROM TABLEA a
LEFTJOIN TABLEB b
ON a.Key = b.Key
WHERE b.Key IS NULL;
https://www.cloudways.com/blog/how-to-join-two-tables-mysql/
This is pure set theory which you can achieve with the minus operation.
select id, name from table1
minus
select id, name from table2
Here's what worked best for me.
SELECT *
FROM #T1
EXCEPT
SELECT a.*
FROM #T1 a
JOIN #T2 b ON a.ID = b.ID
This was more than twice as fast as any other method I tried.
Watch out for pitfalls. If the field Name in Table1 contain Nulls you are in for surprises.
Better is:
SELECT name
FROM table2
WHERE name NOT IN
(SELECT ISNULL(name ,'')
FROM table1)
You can use EXCEPT in mssql or MINUS in oracle, they are identical according to :
http://blog.sqlauthority.com/2008/08/07/sql-server-except-clause-in-sql-server-is-similar-to-minus-clause-in-oracle/
That work sharp for me
SELECT *
FROM [dbo].[table1] t1
LEFT JOIN [dbo].[table2] t2 ON t1.[t1_ID] = t2.[t2_ID]
WHERE t2.[t2_ID] IS NULL
You can use following query structure :
SELECT t1.name FROM table1 t1 JOIN table2 t2 ON t2.fk_id != t1.id;
table1 :
id
name
1
Amit
2
Sagar
table2 :
id
fk_id
email
1
1
amit#ma.com
Output:
name
Sagar
All the above queries are incredibly slow on big tables. A change of strategy is needed. Here there is the code I used for a DB of mine, you can transliterate changing the fields and table names.
This is the strategy: you create two implicit temporary tables and make a union of them.
The first temporary table comes from a selection of all the rows of the first original table the fields of which you wanna control that are NOT present in the second original table.
The second implicit temporary table contains all the rows of the two original tables that have a match on identical values of the column/field you wanna control.
The result of the union is a table that has more than one row with the same control field value in case there is a match for that value on the two original tables (one coming from the first select, the second coming from the second select) and just one row with the control column value in case of the value of the first original table not matching any value of the second original table.
You group and count. When the count is 1 there is not match and, finally, you select just the rows with the count equal to 1.
Seems not elegant, but it is orders of magnitude faster than all the above solutions.
IMPORTANT NOTE: enable the INDEX on the columns to be checked.
SELECT name, source, id
FROM
(
SELECT name, "active_ingredients" as source, active_ingredients.id as id
FROM active_ingredients
UNION ALL
SELECT active_ingredients.name as name, "UNII_database" as source, temp_active_ingredients_aliases.id as id
FROM active_ingredients
INNER JOIN temp_active_ingredients_aliases ON temp_active_ingredients_aliases.alias_name = active_ingredients.name
) tbl
GROUP BY name
HAVING count(*) = 1
ORDER BY name
See query:
SELECT * FROM Table1 WHERE
id NOT IN (SELECT
e.id
FROM
Table1 e
INNER JOIN
Table2 s ON e.id = s.id);
Conceptually would be: Fetching the matching records in subquery and then in main query fetching the records which are not in subquery.
First define alias of table like t1 and t2.
After that get record of second table.
After that match that record using where condition:
SELECT name FROM table2 as t2
WHERE NOT EXISTS (SELECT * FROM table1 as t1 WHERE t1.name = t2.name)
I'm going to repost (since I'm not cool enough yet to comment) in the correct answer....in case anyone else thought it needed better explaining.
SELECT temp_table_1.name
FROM original_table_1 temp_table_1
LEFT JOIN original_table_2 temp_table_2 ON temp_table_2.name = temp_table_1.name
WHERE temp_table_2.name IS NULL
And I've seen syntax in FROM needing commas between table names in mySQL but in sqlLite it seemed to prefer the space.
The bottom line is when you use bad variable names it leaves questions. My variables should make more sense. And someone should explain why we need a comma or no comma.
I tried all solutions above but they did not work in my case. The following query worked for me.
SELECT NAME
FROM table_1
WHERE NAME NOT IN
(SELECT a.NAME
FROM table_1 AS a
LEFT JOIN table_2 AS b
ON a.NAME = b.NAME
WHERE any further condition);
I have two tables, table1 and table2. table1 has 2 rows. table2 has 3 rows. so, totally table1 and table2 have 5 rows. I want to show the 5 rows by selecting table1 and table2 at a time. how todo? can you help me please. don't add any where clause.
depends on what the table structure is. if you have a PK > FK relationship you can join the tables like so
SELECT stuff
FROM table1 t1
JOIN table2 t2 ON t1.someID = t2.someID
if there is no correlation then you can use a UNION
SELECT stuff
FROM table1
UNION
SELECT stuff
FROM table2
One thing to note about using a UNION. the columns have to match so if you have the same type of data in both tables this works fine or else you will have to specify which columns to be selected out.
I have table1 with 3 numbers and table2 with 1 number:
table1 table2
n n
1 1
2
3
I want to select data from table1 that is NOT present in table2 (numbes 2 and 3). I tried:
select table1.* from table1, table2 where table1.n <> table2.n
I also tried other where clauses:
where table1.n not like table2.n
where not table1.n = table2.n
But I don't get the results. I know it can be done in multiple steps, but I wonder if there is a simple query to do it. Thanks
You need to do a LEFT JOIN and look for null values for t2. Like this:
SELECT
t1.n
FROM
table1 AS t1
LEFT JOIN table2 AS t2
ON t1.n = t2.n
WHERE
t2.n IS NULL
Here is link to a great reference for different sorts of JOINS which includes Venn diagrams to help you visualize the different approaches to joining.
http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/
You can do that using NOT IN or NOT EXISTS.
select * from table1
where table1.n not in (select table2.n from table2);
select * from table1
where not exists (select table2.n from table2 where table2.n = table1.n);
I tried both approaches (left join and not in) several times and it took the exact same time (my table is pretty big). Thanks guys!
I have a MYSQL query selecting from two tables. The second table may not necessarily have a matching join id to the first table. Let's use these two as examples:
++++++++++++++++++
table: t1
column: id
column: test_id
column: info
table t2
column: t2id
column: test_id
column: extra_info
++++++++++++++++++
I inserted these following rows into the table (this is just all pseudo at the moment):
insert into t1 values (1, 4, "asd")
insert into t1 values (2, 25, "dfg")
insert into t2 values (1, 25, "123")
Now my goal is to join the two tables together, but I am having issues with the join. if the second table (t2) doesn't seem to have a matching row it makes the join column in the original table NULL? Why is it doing this? Here is an example query:
SELECT * FROM `t1` LEFT JOIN `t2` ON (`t1.test_id` = `t2.test_id`) WHERE `t1.id` = 1;
Now I have absolutely no issues if they match up, but for some reason if there is no row that exists, then test_id from t1 is being set as NULL...My goal is to join these two tables if there is something to join. EDIT: If there is nothing to join then i want to just return the data from t1 by either having all the t2 columns set to NULL or just returning the t1 data. Do I need to do a subquery? and if so what would it be? Thanks :)
Use an INNER JOIN.
SELECT * FROM `t1`
INNER JOIN `t2` ON (`t1.test_id` = `t2.test_id`)
WHERE `t1.id` = 1;
Documentation on JOIN types: http://dev.mysql.com/doc/refman/5.7/en/join.html
That's the definition of LEFT JOIN. It returns rows even if only the left half of the join matches, filling the right side with NULL if needed.
If you want to get only the rows where there's a corresponding right side, use just JOIN instead of LEFT JOIN.
When joining, it is advisable not to use "SELECT *", particularly when you have similarly named columns in multiple tables, as this introduces ambiguity, and you may not get the result intended. I would suggest instead:
SELECT t1.*, t2.t2id, t2.extra_info
FROM `t1`
LEFT JOIN `t2`
ON (`t1.test_id` = `t2.test_id`)
WHERE `t1.id` = 1;
There are multiple different types of joins. I think what you want is "inner join", where only rows that have a match are returned. Check out http://www.w3schools.com/sql/sql_join.asp
I have 2 tables table1 and table2, where table1 contains the data collected so far, and table2 contains table1's data along with some updated/additional data. I need to retrieve only this updated/additional data and insert it into table1.
Now I know I can use NOT IN to do this, but I am not sure it will be a very efficient solution in case of a huge number of records. Any suggestion on what the best approach would be in terms of execution speed?
This can be done with simple join both tables
something like below:
select t1.* from table1 as t1 join table2 as t2 on t1.id=t2.id where ...[]
I'm not sure if i've understand your question correctly but let me give it a try. Suppose you have a design like this:
TableA : {colA, colB, colC, colD, colE}
TableB : {colA, colB, RecC, RecD, RecE}
where Tables (tableA, tableB) is joined on ColA. I Assumed that TableA's columns (colC, ColD, colE) will be updated and the records are based on TableB's columns (recC, recD, recE).
In your statement: I need to retrieve only this updated/additional data and insert it into table1.. I think you want to update TableA's records based on TableB
UPDATE TableA a INNER JOIN TableB b ON a.ColA = b.ColA
SET a.ColC = b.RecC,
a.ColD = b.RecD,
a.ColE = b.RecE
-- WHERE (Condition) -- if you want to have a condition.
so the statement above updates all the records in tableA if colA also exist in tableB since I've used INNER JOIN. You could also use LEFT JOIN.