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);
So I have three tables. I want the first table to match the third table based on their matching ids. Afterwards, I want the third table's id to be replaced by the second table's id (concat'd with a 'g' in front), which is identified through a select query on the first and second table.
Here's my rough idea of how it should go, just not too sure of how to match, then use tbl2's id:
UPDATE tbl3 SET col=CONCAT('g',tbl2.id) WHERE
id IN (
SELECT tbl1.id, tbl2.id FROM tbl1 left join tbl2 on tbl1.id = tbl2.id
WHERE blah='blah');
Is this possible in MySQL alone or will I have to do it in php using multiple queries?
So I found a MySQL fiddle site. Not bad, but doesn't allow UPDATE. Anyway, at least you can see the SELECT working:
http://sqlfiddle.com/#!9/bfdb66/7
Here's the SQL:
UPDATE tbl3 t3
LEFT JOIN tbl1 t1 ON t3.id=t1.id
LEFT JOIN tbl2 t2 ON t2.id=t1.id
SET t3.col=CONCAT('g',t2.id) WHERE
t3.blah = 'blah' AND t2.id IS NOT NULL;
According to this spec:
I want the first table to match the third table based on their matching ids
I want the third table's id to be replaced by the second table's id
which is identified through a select query on the first and second table
Let me know if I've misunderstood!
I am trying to upload data from cvs file to mysql. I want to filter the duplicate values of column roll.
for eg.
Table1
-----------
id name roll
1 Nirdos 4
2 krishn 2
3 shrest 2
If data is like this I want to insert first 2 rows because third row have duplicate row with second row.
Thnks In Advance
You can use the following INSERT INTO ... SELECT statement to do the insert:
INSERT INTO targetTable (id, name, roll)
SELECT t1.id, t1.name, t1.roll
FROM sourceTable AS t1
JOIN (SELECT roll, MIN(id) AS min_id
FROM sourceTable
GROUP BY roll) AS t2
ON t1.roll = t2.roll AND t1.id = t2.min_id
In case of a duplicate roll value, this query will insert the record having the minimum id value.
MySQL database provides a facility where you can make the roll column unique, and the database itself won't take duplicate input for that particular column.
The second method would be to check for duplicate entries before entering a new row and match the data with the data you are about to enter
I want to merge the value records as single row based on ID value.I want to display table1 value along with table2 value as single row. I want to display all in single record for the id=15.In table 1 ID is sub_id in table 2.
I want output as
Id content_value value as(15,cake,chocolate,enila,strabery)
select a.*,b.CONTENT_VALUE as multitype from album as a,album_details as b where a.ID=b.SUB_ID
Not possible to get as different columns for each value or content_value since the number of rows is dynamic.You can get the values like this by joining two tables. ie as two columns (ID and all content_value & value).
SELECT t1.ID, CONCAT_WS(',', t1.content_value, GROUP_CONCAT(t2.value)) AS contents FROM table1 t1
INNER JOIN table2 t2
ON t2.sub_id = t1.ID
GROUP BY t1.ID;
What I'm trying to do should be really simple. I have two tables with the following columns:
Table 1:
Name, Level
Table 2:
Name, Cost
Name is the primary key. I want to combine both table's data into one table that has all three columns. What I've been trying to do is add a Cost column into Table 1 and copy all the Cost values from Table 2 into it. I've tried numerous suggestions from other threads on this site and I've never had one work for me. The new Cost column in Table 1 never budged with any new values. Why?
I am doing this on MySQL Workbench on Ubuntu.
Here's one that I tried using (New cost column already made for Tbl1):
UPDATE Tbl1
SET Cost = (
SELECT Cost
FROM Tbl2
WHERE Name = 'SpecificName')
WHERE Name = 'SpecificName;
This works when I specify individual rows but it doesn't work when I replace Name = 'SpecificName' with something like "Tbl1.Name = Tbl2.Name"
The problem you face is when some names are in one table but not the other. Here is one method, using a single create table as:
create table NameLevelCost as
select n.name, t1.level, t2.cost
from (select name from table1
union
select name from table2
) n left join
table1 t1
on t1.name = n.name left join
table2 t2
on t2.name = n.name;
This assumes that name is unique in each of the tables.
update Tbl1 t1 left join Tbl2 t2 on t2.Name = t1.Name set t1.Cost = t2.Cost;