匹配或为空的列的行删除查询

4
我有一张表格,其中有几列。我需要比较其中的几列并删除它们彼此匹配或为空的行。换句话说,我只需要保留除NULL之外还有差异的行。(如果有影响的话,我将对具有不同比较列数量的表格运行此操作,有时会有很多列,因此专注于仅有三列的查询不起作用。)
所以,如果我的表格是:
ID  TITLE   VALUE_1 VALUE_2 VALUE_3
1   One     AAA     NULL    NULL
2   Two     NULL    AAA     AAA
3   Three   AAA     AAA     AAA
4   Four    NULL    NULL    NULL
5   Five    AAA     BBB     CCC
6   Six     AAA     BBB     NULL
7   Seven   NULL    DDD     EEE
8   Eight   AAA     AAA     BBB

运行查询后,我希望能得到以下结果:
ID  TITLE   VALUE_1 VALUE_2 VALUE_3
5   Five    AAA     BBB     CCC
6   Six     AAA     BBB     NULL
7   Seven   NULL    DDD     EEE
8   Eight   AAA     AAA     BBB

3
如果你的数据被规范化,这将变得简单许多。 - Sean Lange
3个回答

3
select * from table
where v1 <> v2 or v1 <> v3 or v2 <> v3

这将返回其中任何一对都会为TRUE的行。因此,将该谓词与NOT IN包围起来将给出要删除的所需集合:
delete t where id not in(select id from t where v1 <> v2 or v1 <> v3 or v2 <> v3)

这是 SQL Fiddle 的示例链接:http://sqlfiddle.com/#!3/ea7172/8

太好了!它完美地运行了。谢谢!我猜这是一个愚蠢的问题,但你能解释一下为什么那个选择不返回前两行吗?在两行中,v1 <> v2('aaa'不为NULL),但这些行没有被选择,因此也没有被删除。再次强调,这正是我想要的,我只是想了解它是如何工作的。再次感谢。 - THEMEDIA
好的,SELECT 语句将只选择 WHERE 子句中谓词评估为 true 的行。如果它评估为 false 或 unknown(如果至少一侧为 null,则为 unknown),则该行将被过滤掉。例如,第 1 行。Aaa <> null 或 aaa <> null 或 null <> null => unknown 或 unknown 或 unknown => unknown。它将被过滤掉。对于第 7 行。Null <> ddd 或 null <> eee 或 ddd <> eee => unknown 或 unknown 或 true => true。因此,第 7 行不会被过滤掉,它将出现在结果集中。 - Giorgi Nakeuri
我还有点困惑,但现在清楚多了。再次感谢您的查询和解释。 - THEMEDIA
这是三值逻辑。谓词可以评估为3个值:true,false,unknown。v1 <> v2 or v1 <> v3 or v2 <> v3 这是谓词。将过滤掉仅评估为TRUE的行。a = a 评估为true。a = b 评估为false。a = null 评估为unknown。null = null 评估为unknown。a <> a 评估为false。a <> b 评估为true。a <> null 评估为unknown。null <> null 评估为unknown。 - Giorgi Nakeuri

1
 Delete from tablename 
      where (Value_1 is Null And value_2 is null) 
             or (Value_2 is Null And value_3 is null)
             or (Value_1 is Null And value_3 is null)
             or (Value_1 = value_2)
             or (Value_1 = value_3)
             or (Value_3 = value_2)

如果有两列为空或任意两列匹配,则应该能够删除此内容。如果您想知道,SQL Server 中没有字符串比较函数。

我认为这不会给他想要的东西。一个空值可以存在于一个或多个列中,他只想在有两个不为空且具有相同数据的列时删除该行。 - Tony Hinkle
@TonyHinkle 是的,没错,我需要保留只有除NULL以外其他不同的行。也许我漏掉了什么,但是第一行有AAA, NULL, NULL,因此被删除,因为没有除NULL以外其他的差异。 - THEMEDIA
你试过我的代码了吗?它应该可以正常工作。让我知道一下。 - Coding Enthusiast
你的样本输出提示了不同的东西。在你的会议后让我知道。 - Coding Enthusiast
我测试了你的查询。这将删除任何两个为空的行。在上面的示例中,这是可以的,但有时我比三列更多,有时甚至更多。我可以通过添加更多字段来使其工作。然而,它也会在它们都不为空且三个字段中有两个相同时进行删除,因此它不符合“保留除null之外的差异行”的条件。谢谢你。 - THEMEDIA
显示剩余2条评论

0

在你的DELETE语句中,可以像这样使用ISNULL

Where IsNull (Value_1, 'SomeValueThatWillNeverBeInTheTable') = IsNull (Value_2, 'SomeValueThatWillNeverBeInTheTable')


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接