如何在合并数据集之前检查行是不是存在(SQL Server)

Posted

技术标签:

【中文标题】如何在合并数据集之前检查行是不是存在(SQL Server)【英文标题】:How to check for row existence to before merging datasets (SQL Server)如何在合并数据集之前检查行是否存在(SQL Server) 【发布时间】:2020-06-18 17:57:24 【问题描述】:

我正在尝试合并两个数据集,并想检查其中一个表上是否已经存在一行。

在这里,我想从 table_1 中选择 table_2 上尚未匹配 3 列值的所有内容。

表 1

| id | key   | value   |
|----|-------|---------| 
| 1  | brand | alpha   |
| 1  | color | red     |
| 2  | brand | charlie |

表 2

| id | key   | value   |
|----|-------|---------| 
| 2  | brand | charlie |
| 2  | color | yellow  |

期望的输出

| id | key   | value   |
|----|-------|---------| 
| 2  | color | yellow  |

查询

select [id], [key], [value]
from db..table_1
where not exists (
  select
  [id], [key], [value]
  from db..table_2
)

如何在 SQL Server 中实现这一点?

【问题讨论】:

您是否认为“重复”行具有相同的id、相同的key、相同的id + key 或相同的id + key + value?我觉得如果这些是你真正的列名,它们会让你很难唯一地识别一行。也许您可以提供两个表中的一些示例数据,带有边缘情况(例如相同的 id 和相同的键但不同的值),并指出您希望排除 b 中的哪些行? 是的,在所有 3 列上重复匹配。已添加示例数据... 【参考方案1】:

有很多方法,但我想这个答案必须改变,因为根据列名,我认为您的要求是模棱两可的。这是三种不同的方法,但输出可能会有所不同,例如,如果在 t1 中有重复已经存在

-- except
SELECT [id], [key], [value] FROM dbo.table_1
EXCEPT
SELECT [id], [key], [value] FROM dbo.table_2;

-- not exists (must be correlated to t1!)
SELECT [id], [key], [value] 
FROM dbo.table_1 AS t1
WHERE NOT EXISTS
(
  SELECT 1 FROM dbo.table_2 AS t2
    WHERE t2.[id]    = t1.[id]
      AND t2.[key]   = t1.[key]
      AND t2.[value] = t1.[value]
);

-- left outer join    
SELECT t1.[id], t1.[key], t1.[value]
  FROM dbo.table_1 AS t1
  LEFT OUTER JOIN dbo.table_2 AS t2
       ON t2.[id]    = t1.[id]
      AND t2.[key]   = t1.[key]
      AND t2.[value] = t1.[value]
 WHERE t2.[id] IS NULL;

一些performance aspects here。

如果表之间有不同的排序规则,您可以使用 COLLATE 子句解决冲突,但您需要确保映射到正确的排序规则以按照您期望的方式比较值(请记住,如果您映射到区分大小写或二进制排序规则,banana BANANA)。

CREATE TABLE dbo.t1(a nvarchar(32) COLLATE Slovenian_BIN);

CREATE TABLE dbo.t2(a nvarchar(32) COLLATE Latin1_General_CS_AS_KS_WS);

SELECT a FROM dbo.t1 
EXCEPT 
SELECT a COLLATE Slovenian_BIN FROM dbo.t2;
         ---------------------

【讨论】:

除了表格有不同的排序规则外,是否有解决方法? @Matthew 当然,您可以在 t2 中的每个基于字符串的列中添加 COLLATE 子句,以便它们匹配 t1,但请注意,这可能会使您认为应该匹配的内容不再匹配(例如区分大小写或二进制排序规则,你想要banana = BananA,还是不要?)。 现在正在解决这个问题...这是两个解决方案吗?一个是except,一个是where not exists?这些都是不同长度的返回列表......第二个似乎在ambiguous column name上出错。 @Matthew 您可以测试三种不同的方式(因为它们的执行方式可能因类型/架构/索引而异)。

以上是关于如何在合并数据集之前检查行是不是存在(SQL Server)的主要内容,如果未能解决你的问题,请参考以下文章

如何在保存在 Mongoose 之前检查数据库中是不是存在嵌入式文档

如何在显示列之前检查 SELECT 语句是不是存在

如何在将大量数据插入数据库之前检查记录是不是存在?

如何在创建存储过程之前检查它是不是存在

PHP在更新SQL表之前检查文件是不是存在

Oracle - 在删除其他表中的几行之前检查行是不是存在