简体   繁体   English

如何从一个表中选择另一张表中不存在的所有记录?

[英]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 .首先定义表的别名,如t1t2 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.这就是策略:创建两个隐式临时表并将它们合并。

  1. 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.第一个临时表来自第一个原始表的所有行的选择,您想要控制的字段不存在于第二个原始表中。
  2. 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.第二个隐式临时表包含两个原始表的所有行,这些行与您要控制的列/字段的相同值匹配。
  3. 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.联合的结果是一个表,该表具有多个具有相同控制字段值的行,以防两个原始表上的该值匹配(一个来自第一个选择,第二个来自第二个选择)如果第一个原始表的值与第二个原始表的任何值不匹配,则只有一行具有控制列值。
  4. 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.当计数为 1 时,不匹配,最后,您只选择计数等于 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

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 ID name名称
1 1 Amit阿米特
2 2 Sagar萨加尔

table2 :表2:

id ID fk_id fk_id email电子邮件
1 1 1 1 amit@ma.com 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.

相关问题 如何 select 一个表中的所有记录在另一个表中不存在于另一个表中的某些条件下? - How to select all records from one table that do not exist in another table for certain condition in another table? 如何从一张表中选择关系表中不存在的所有记录? - how to select all records from one table that not exist in relation table? 如何显示一个表中不存在于另一表中的记录 - How to show records from one table that do not exist in another table 如何从一个表中选择特定年份不存在的所有记录? - How to select all records from one table that do not exist in particular year? Select 基于条件的一个表中的所有记录,而不是另一个表中的所有记录 - Select all records from one table not in another table based on a condition sql-从一个表中选择另一个表中不存在的记录 - sql - Select records from one table that do not exist in the other 从一个表中选择所有记录,并在第二个表中没有其他记录的情况下返回空值 - select all records from one table and return null values where they do not have another record in second table 如何从一个表中选择与SQL Server中的另一个表完全匹配的所有记录? - How to select all records from one table that exactly match another table in SQL Server? 如何选择表中的所有记录(不包括另一个记录) - How to select all records in a table excluding records from another SQLite - 如何从一个表中的 select 记录不在另一表中 - SQLite - How to select records from one table that are not in another table
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM