【问题标题】:SQL help: find rows in one table which don't exist in second table based on values in two columnsSQL帮助:根据两列中的值查找一个表中不存在于第二个表中的行
【发布时间】:2010-01-22 19:11:01
【问题描述】:

我有两张桌子。我试图根据两列中的值在一个表中查找第二个表中不存在的行。 (我已将表格简化为仅包含两列)。两个表之间没有主键/外键。看起来很简单,但我现在脑子有问题!

DDL:
CREATE TABLE [dbo].[Table_1](
    [firstname] [nchar](10) NULL,
    [lastname] [nchar](10) NULL
) 

CREATE TABLE [dbo].[Table_2](
    [firstname] [nchar](10) NULL,
    [lastname] [nchar](10) NULL
) 

-- 创建样本数据

INSERT INTO [dbo].[Table_1]([firstname], [lastname])
SELECT N'John      ', N'Doe       ' UNION ALL
SELECT N'John      ', N'Smith     '
INSERT INTO [dbo].[Table_2]([firstname], [lastname])
SELECT N'John      ', N'Doe       '

--我的失败尝试。我期待约翰史密斯回来

SELECT t.* FROM Table_1 AS t
WHERE NOT EXISTS
(SELECT t2.* FROM Table_2 AS t2
WHERE t.firstname <> t2.firstname
AND t.lastname <> t2.lastname)

SELECT * FROM Table_1 AS t
JOIN Table_2 AS t2
ON t.firstname <> t2.firstname
AND t.lastname <> t2.lastname

【问题讨论】:

  • 请说您并没有真正使用 nchar 数据类型作为名称。同样,如果没有任何其他识别信息,您怎么知道 table1 中的 John Smith 与 table2 中的 John Smith 相同?名称不是唯一的,您不应该计划它们是唯一的。虽然下面的查询可能会为您提供预期的结果,但它们可能不会给出正确的结果。
  • 这只是我快速鞭打的一个例子。是的,它应该是 nvarchar,即使名称相同,人也是独一无二的。

标签: sql tsql


【解决方案1】:

这个怎么样:

SELECT * 
FROM Table_1 AS t1
LEFT OUTER JOIN Table_2 AS t2
ON t1.firstname = t2.firstname
AND t1.lastname = t2.lastname
WHERE t2.firstname IS NULL AND t2.lastname IS NULL

就我而言,我只得到了约翰·史密斯。

您基本上是在公共字段上的表之间进行外部联接 - 在这两种情况下都存在的那些行将具有t1t2 的值。

那些仅存在于t1 中的行将没有第二个表t2 的任何值。

【讨论】:

  • 我的第一个查询应该有 = 而不是 。我正在复制东西,却忘记了这一点。谢谢。
  • 如何更改此查询以删除那些选定的行?
  • @Mateusz:您可以将其“包装”成 CTE ;WITH CTE AS (SELECT.....),然后添加 DELETE FROM Table_1 WHERE CTE.IDColumn = ..... 或类似的东西...
【解决方案2】:

我认为这应该可行:

SELECT t.* FROM Table_1 AS t
 LEFT JOIN Table_2 t2 ON (t.firstname = t2.firstname AND t.lastname = t2.lastname)
WHERE t2.firstname IS NULL AND t2.lastname IS NULL

但我很惊讶你的第一次尝试没有成功:

SELECT t.* FROM Table_1 AS t
WHERE NOT EXISTS
(SELECT t2.* FROM Table_2 AS t2
WHERE t.firstname <> t2.firstname
AND t.lastname <> t2.lastname)

【讨论】:

  • 第二个查询必须检查 firstname 和 lastname 列上的 equality(不是不等式)!如果你这样做,它也有效。 ...... WHERE t.firstname = t2.firstname AND t.lastname = t2.lastname
【解决方案3】:

外连接很好,但我发现这种方法通常在大量数据上执行得更快。

SELECT * 
FROM Table_1 AS t1
WHERE NOT EXISTS
    (
        SELECT *
        FROM Table_2 AS t2
        WHERE t1.firstname = t2.firstname
            AND t1.lastname = t2.lastname
    )

【讨论】:

    【解决方案4】:

    您可以尝试使用 ON 子句中的两列进行左外连接。

    然后使用 WHERE 子句过滤掉两个表都匹配的任何内容

    SELECT * FROM table_1 AS one
    LEFT OUTER JOIN table_2 AS two
    ON one.firstname = two.firstname
    AND one.lastname = two.lastname
    WHERE two.firstname IS NULL AND two.lastname IS NULL
    

    【讨论】:

      猜你喜欢
      • 2010-10-23
      • 2020-04-08
      • 2015-06-03
      • 1970-01-01
      • 1970-01-01
      • 2012-08-18
      • 1970-01-01
      • 2023-03-29
      • 2018-05-05
      相关资源
      最近更新 更多