SQL:有没有办法找到重复项并将它们标记为带有大小写的新列

Posted

技术标签:

【中文标题】SQL:有没有办法找到重复项并将它们标记为带有大小写的新列【英文标题】:SQL : Is there any way to find Duplicates and flag them as new column with case 【发布时间】:2021-02-26 20:31:03 【问题描述】:

我正在尝试在表中查找重复项并想添加一个新的标志列。 以下示例数据:

Column A        Column B
1                888
1                999
1                777
1                777
2                444
2                444
3                555
4                222
-5               333
-5               672
-5               045        

期望的输出:

Column A        Column B         Flag_output
1                888              DUPLICATE
1                999              DUPLICATE
1                777              NULL
1                777              NULL
2                444              NULL
2                444              NULL
3                555              NULL
4                222              NULL
-5               333              DUPLICATE
-5               672              DUPLICATE
-5               045              DUPLICATE

案例 1:当 A 列具有相同的值而 B 列中的值不同时(例如 A 列中的值 1) - 应标记为 DUPLICATE

案例 2:当 A 列在多行中与 B 列中的相同值具有相同的值时(例如 A 列中的值 2) - 应标记为空

案例 3:当 A 列和 B 列具有唯一值时(例如 A 列中的值 34) - 也应该是标记为NULL

任何帮助将不胜感激。

【问题讨论】:

我不明白“1”的行如何根据您的条件具有不同的标志值。 【参考方案1】:

根据您的描述,我可以将您的条件表述为b 的最小值和最大值对于a 不同,然后标记为'duplicate'

为此,请使用窗口函数:

select t.*,
       (case when min(b) over (partition by a) <> max(b) over (partition by a)
             then 'duplicate'
        end) as flag_output
from t;

根据数据,您似乎想要:

select t.*,
       (case when count(*) over (partition by a, b) = 1 and
                  count(*) over (partition by a) > 1
             then 'duplicate'
        end) as flag_output
from t;

也就是说,仅当a 有多个值时才标记单例值。

【讨论】:

【参考方案2】:

编辑: @Gordon Linoff answered 在我打字的时候。一定要先尝试他的解决方案,因为它可能比这更有效。


鉴于以下情况:

A   | B
--- | ---
1   | 888   
1   | 999
1   | 777
1   | 777

您是第一次遇到A=1,所以它不能是DUPLICATE,而必须是NULL

A   | B   | Result
--- | --- | ---
1   | 888 | NULL     
1   | 999 |
1   | 777 | 
1   | 777 | 

然后您将第二次遇到A=1,其值为B。这会将两行标记为DUPLICATE

A   | B   | Result
--- | --- | ---
1   | 888 | DUPLICATE   
1   | 999 | DUPLICATE
1   | 777 | 
1   | 777 | 

还有第三个A=1 实例,它还有一个不同的值B。这三个都是DUPLICATEs。

A   | B   | Result
--- | --- | ---
1   | 888 | DUPLICATE   
1   | 999 | DUPLICATE
1   | 777 | DUPLICATE
1   | 777 | 

您第四次看到A=1 时,它有一个您之前见过的B 值(B=777),它将两行都标记为NULL

A   | B   | Result
--- | --- | ---
1   | 888 | DUPLICATE   
1   | 999 | DUPLICATE
1   | 777 | NULL
1   | 777 | NULL

我的解决方案计算表中A 的每个值的实例以及每个A, B 对的匹配数。这些子结果连接到主表以获取您的结果。 Try it out.

架构

CREATE TABLE Sample (A int, B int)

查询

SELECT s.A, s.B,
  CASE 
    WHEN m.Matches > 1 THEN NULL
    WHEN i.Instances = 1 THEN NULL
    ELSE 'DUPLICATE'    
  END AS Result
FROM Sample s 
  INNER JOIN (SELECT A, COUNT(*) AS Instances FROM Sample GROUP BY A) i
    ON s.A = i.A
  INNER JOIN (SELECT A, B, COUNT(*) AS Matches FROM Sample GROUP BY A, B) m
    ON s.A = m.A AND s.B = m.B
ORDER BY A, B

【讨论】:

以上是关于SQL:有没有办法找到重复项并将它们标记为带有大小写的新列的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法更快地运行 OpenCV 的 SIFT?

带有 INSERT OUTPUT 的 SQL 语法错误 [重复]

有没有办法将“%”符号添加到我在 Oracle SQL 中的透视结果中并将它们转换为 to_char

有没有办法遍历 ListView 的所有子视图并将它们转换为 TextView

如何在文本中找到像“e3”这样的特殊标记并将它们替换为列表中的匹配数据?

循环遍历对象数组,并将它们转换为 UL 中的 LI 项 [重复]