[英]How to select all records from one table that do not exist in another table?
table1 (id, name)
表 1(ID,名称)
table2 (id, name)表2(ID,名称)
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.答:从概念上讲,我们从
table1
中选择所有行,并且对于每一行,我们尝试在table2
中找到与name
列具有相同值的行。 If there is no such row, we just leave the table2
portion of our result empty for that row.如果没有这样的行,我们只需将该行的结果的
table2
部分留空。 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
).最后,我们忽略结果中的所有字段,除了
name
列(我们确定存在的字段,来自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虽然它可能不是在所有情况下都可能是性能最高的方法,但它应该适用于几乎所有尝试实现ANSI 92 SQL的数据库引擎
You can either do你可以做
SELECT name
FROM table2
WHERE name NOT IN
(SELECT name
FROM table1)
I don't have enough rep points to vote up froadie's answer .我没有足够的代表点来投票赞成froadie 的回答。 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. FAR 在实践中是否更有效。 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.
我不知道为什么,但是我正在针对 800k+ 记录运行它,并且由于上面发布的第二个答案的优势,差异是巨大的。 Just my $0.02.
只是我的 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/https://www.cloudways.com/blog/how-to-join-two-tables-mysql/
This is pure set theory which you can achieve with the minus
operation.这是纯集理论,您可以通过
minus
运算来实现。
select id, name from table1
minus
select id, name from table2
Watch out for pitfalls.注意陷阱。 If the field
Name
in Table1
contain Nulls you are in for surprises.如果
Table1
中的字段Name
包含 Null,您会感到惊讶。 Better is:更好的是:
SELECT name
FROM table2
WHERE name NOT IN
(SELECT ISNULL(name ,'')
FROM table1)
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.这比我尝试的任何其他方法快两倍多。
You can use EXCEPT
in mssql or MINUS
in oracle, they are identical according to :您可以在 mssql 中使用
EXCEPT
或在 oracle 中使用MINUS
,它们是相同的:
http://blog.sqlauthority.com/2008/08/07/sql-server-except-clause-in-sql-server-is-similar-to-minus-clause-in-oracle/ 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
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
.首先定义表的别名,如
t1
和t2
。 After that get record of second table.之后获得第二张桌子的记录。 After that match that record using
where
condition:之后使用
where
条件匹配该记录:
SELECT name FROM table2 as t2
WHERE NOT EXISTS (SELECT * FROM table1 as t1 WHERE t1.name = t2.name)
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.这就是策略:创建两个隐式临时表并将它们合并。
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
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.我已经看到 FROM 中的语法需要在 mySQL 中的表名之间使用逗号,但在 sqlLite 中它似乎更喜欢空格。
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.
有人应该解释为什么我们需要逗号或不使用逗号。
You can use following query structure :您可以使用以下查询结构:
SELECT t1.name FROM table1 t1 JOIN table2 t2 ON t2.fk_id != t1.id;
table1 :表格1 :
id ![]() |
name![]() |
---|---|
1 ![]() |
Amit![]() |
2 ![]() |
Sagar![]() |
table2 :表2:
id ![]() |
fk_id ![]() |
email![]() |
---|---|---|
1 ![]() |
1 ![]() |
amit@ma.com ![]() |
Output:输出:
name![]() |
---|
Sagar![]() |
I tried all solution above but 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 );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.