【问题标题】:How to update sql records by comparing duplicate strings?如何通过比较重复字符串来更新sql记录?
【发布时间】:2019-11-01 16:34:04
【问题描述】:

我有一张下表:

id   |  echantillon_dta  |   Est_en_double 
1    |   Bonjour         |      null
2    |   Bonjour         |      null
3    |   Bonjour         |      null
4    |   Joke            |      null
5    |   Joke            |      null
6    |                   |      null 

处理后查询会显示如下:

id   |   echantillon_dta        |   Est_en_double 
1    |   Bonjour         |      1
2    |   Bonjour         |      1 
3    |   Bonjour         |      1 
4    |   Joke            |      4
5    |   Joke            |      4
6    |                   |      null 

如何比较字符串与字符串?以及如何像这样更新列?

【问题讨论】:

  • 欢迎来到 Stack Overflow!您能否向我们展示您的尝试?
  • GROUP BY 和 ORDER BY 可以很好地处理字符串,不知道你是如何得出这个结论的。对于许多不同的解决方案,查找重复项是一个非常常见的问题。如果您想阅读它,请查看 Chris Saxon 的博客:blogs.oracle.com/sql/…

标签: sql


【解决方案1】:

当 Record_Details 相同时,您可以使用 min(id) 更新。

还有一个错误描述:
6 | Nope | 6 //No duplicates found, stay null
id 6 不重复但isDuplicate column 值是6,不应该是null吗?
所以我用having count(1) > 1 来解决它。

CREATE TABLE Table1
  ("id" int, "Record_Details" varchar2(11), "isDuplicate" varchar2(4))
;
INSERT ALL 
  INTO Table1 ("id", "Record_Details", "isDuplicate")
       VALUES (1, 'Hello World', NULL)
  INTO Table1 ("id", "Record_Details", "isDuplicate")
       VALUES (2, 'Hello World', NULL)
  INTO Table1 ("id", "Record_Details", "isDuplicate")
       VALUES (3, 'Hello World', NULL)
  INTO Table1 ("id", "Record_Details", "isDuplicate")
       VALUES (4, 'Joke', NULL)
  INTO Table1 ("id", "Record_Details", "isDuplicate")
       VALUES (5, 'Joke', NULL)
  INTO Table1 ("id", "Record_Details", "isDuplicate")
       VALUES (6, 'Nope', NULL)
SELECT * FROM dual
;
update (
  select T.*
     , (select min("id") 
        from Table1 Tmp 
        where Tmp."Record_Details" = T."Record_Details"
        group by Tmp."Record_Details" having count(1) > 1 --No duplicates found, stay null

     ) as "new_isDuplicate"
  from Table1 T
)
set "isDuplicate" = "new_isDuplicate"
6 行受影响
select * from Table1
编号 |记录_详情 |是重复的 -: | :------------- | :---------- 1 |你好世界 | 1 2 |你好世界 | 1 3 |你好世界 | 1 4 |笑话 | 4 5 |笑话 | 4 6 |没有 |

db小提琴here

【讨论】:

  • Oracle DB 上的 GROUP BY 语句失败,出现 [42000][932] ORA-00932:不一致的数据类型:预期 - 出现 CLOB 错误。大概是因为我不能 GROUP BY 字符串类型记录
  • @CuriosLoner 关注这个答案stackoverflow.com/questions/20678881/…
【解决方案2】:

您可以使用MERGE 语句和分析函数来查找重复项:

Oracle 设置

CREATE TABLE Table_name ( id, Record_Details, isDuplicate ) AS
SELECT 1, 'Hello World', CAST( NULL AS NUMBER ) FROM DUAL UNION ALL
SELECT 2, 'Hello World', NULL FROM DUAL UNION ALL
SELECT 3, 'Hello World', NULL FROM DUAL UNION ALL
SELECT 4, 'Joke',        NULL FROM DUAL UNION ALL
SELECT 5, 'Joke',        NULL FROM DUAL UNION ALL
SELECT 6, 'Nope',        NULL FROM DUAL;

合并

MERGE INTO table_name dst
USING (
  SELECT ROWID rid,
         MIN( id ) OVER ( PARTITION BY Record_details ) AS dupe_id
  FROM   table_name
) src
ON (
    dst.ROWID = src.RID
AND dst.id <> src.dupe_id -- remove this line if you want to update all rows
) 
WHEN MATCHED THEN
  UPDATE SET isDuplicate = dupe_id;

输出

身份证 |记录详细信息 |复制 -: | :------------- | ----------: 1 |你好世界 | 2 |你好世界 | 1 3 |你好世界 | 1 4 |笑话 | 5 |笑话 | 4 6 |没有 |

db小提琴here

【讨论】:

    【解决方案3】:

    您似乎想要最小的id 和相同的record_details

    这应该可行:

    select t.*,
           min(id) over (partition by record_details) as isDuplicate
    from t;
    

    如果您希望这是 update,关联子查询是一种简单的方法:

    update t
        set isduplicate = (select min(t2.id)
                           from t t2
                           where t2.record_details = t.record_details
                          );
    

    【讨论】:

    • @CuriosLoner 。 . .您的问题中没有提到CLOBs。
    • @CuriosLoner 。 . .您可能应该问一个 问题。此问题已得到解答,更改问题将使答案无效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 2020-04-30
    • 2013-01-26
    • 2013-04-15
    • 2018-07-09
    • 2017-06-27
    相关资源
    最近更新 更多