【发布时间】:2011-02-10 18:58:23
【问题描述】:
table1 (id, name)
table2 (id, name)
查询:
SELECT name
FROM table2
-- that are not in table1 already
【问题讨论】:
-
查看底部带有 UNION 的解决方案,它比此处列出的任何其他解决方案都要快几个数量级。
标签: sql sql-server tsql
table1 (id, name)
table2 (id, name)
查询:
SELECT name
FROM table2
-- that are not in table1 already
【问题讨论】:
标签: sql sql-server tsql
上述所有查询在大表上都非常慢。需要改变策略。这是我用于我的数据库的代码,您可以音译更改字段和表名。
这是策略:创建两个隐式临时表并将它们合并。
看起来并不优雅,但比上述所有解决方案都要快几个数量级。
重要提示:启用要检查的列上的索引。
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
【讨论】:
您可以使用以下查询结构:
SELECT t1.name FROM table1 t1 JOIN table2 t2 ON t2.fk_id != t1.id;
表 1:
| id | name |
|---|---|
| 1 | Amit |
| 2 | Sagar |
表2:
| id | fk_id | |
|---|---|---|
| 1 | 1 | amit@ma.com |
输出:
| name |
|---|
| Sagar |
【讨论】:
我尝试了上述所有解决方案,但在我的情况下不起作用。以下查询对我有用。
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 );
【讨论】:
首先定义表的别名,如t1 和t2。
之后获得第二张桌子的记录。
之后使用where 条件匹配该记录:
SELECT name FROM table2 as t2
WHERE NOT EXISTS (SELECT * FROM table1 as t1 WHERE t1.name = t2.name)
【讨论】:
我没有足够的代表点来投票 froadie's answer。但我不得不不同意Kris's answer 上的cmets。以下答案:
SELECT name
FROM table2
WHERE name NOT IN
(SELECT name
FROM table1)
FAR 在实践中是否更有效。我不知道为什么,但是我正在针对 800k+ 记录运行它,并且由于上面发布的第二个答案的优势,差异是巨大的。只是我的 0.02 美元。
【讨论】:
查看查询:
SELECT * FROM Table1 WHERE
id NOT IN (SELECT
e.id
FROM
Table1 e
INNER JOIN
Table2 s ON e.id = s.id);
概念上是:在子查询中获取匹配的记录,然后在主查询中获取不在子查询中的记录。
【讨论】:
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/
【讨论】:
我将在正确答案中重新发布(因为我还不够酷,无法发表评论)......以防其他人认为需要更好地解释。
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
我已经看到 FROM 中的语法需要在 mySQL 中的表名之间使用逗号,但在 sqlLite 中它似乎更喜欢空格。
最重要的是,当您使用错误的变量名称时,它会留下问题。我的变量应该更有意义。并且应该有人解释为什么我们需要逗号或不使用逗号。
【讨论】:
你可以这样做
SELECT name
FROM table2
WHERE name NOT IN
(SELECT name
FROM table1)
或
SELECT name
FROM table2
WHERE NOT EXISTS
(SELECT *
FROM table1
WHERE table1.name = table2.name)
请参阅this question 了解实现此目的的 3 种技术
【讨论】:
这是最适合我的方法。
SELECT *
FROM @T1
EXCEPT
SELECT a.*
FROM @T1 a
JOIN @T2 b ON a.ID = b.ID
这是我尝试过的任何其他方法的两倍多。
【讨论】:
这对我很有效
SELECT *
FROM [dbo].[table1] t1
LEFT JOIN [dbo].[table2] t2 ON t1.[t1_ID] = t2.[t2_ID]
WHERE t2.[t2_ID] IS NULL
【讨论】:
SELECT t1.name
FROM table1 t1
LEFT JOIN table2 t2 ON t2.name = t1.name
WHERE t2.name IS NULL
问:这里发生了什么?
A:从概念上讲,我们从table1 中选择所有行,并且对于每一行,我们尝试在table2 中找到与name 列具有相同值的行。如果没有这样的行,我们只需将该行的结果的table2 部分留空。然后我们通过仅选择结果中不存在匹配行的那些行来限制我们的选择。最后,我们忽略结果中的所有字段,除了name 列(我们确定存在的字段,来自table1)。
虽然它可能不是在所有情况下都可能是性能最高的方法,但它应该适用于几乎所有尝试实现 ANSI 92 SQL 的数据库引擎
【讨论】:
您可以在 mssql 中使用 EXCEPT 或在 oracle 中使用 MINUS,它们是相同的:
【讨论】:
注意陷阱。如果Table1 中的字段Name 包含Null,您会感到惊讶。
更好的是:
SELECT name
FROM table2
WHERE name NOT IN
(SELECT ISNULL(name ,'')
FROM table1)
【讨论】:
这是纯集合论,您可以通过 minus 操作来实现。
select id, name from table1
minus
select id, name from table2
【讨论】: