【问题标题】:Finding duplicate values in multiple colums in a SQL table and count for chars在 SQL 表的多个列中查找重复值并计算字符数
【发布时间】:2022-01-27 11:18:55
【问题描述】:

参考这个问题:

Finding duplicate values in multiple colums in a SQL table and count

我的表结构如下:

id name1 name2 name3  ...
 1 Hans  Peter Frank
 2 Hans  Frank Peter
 3 Hans  Peter Frank
 4 Paul  Peter Hans
 .
 .
 .

我使用以下命令来显示重复项和计数:

SELECT COUNT(name1), name1, name2, name3 
FROM table 
GROUP BY name1, name2, name3 
HAVING (COUNT(name1) > 1) AND (COUNT(name2) > 1) AND (COUNT(name3) > 1)

这个命令给我的计数是 2。我想知道第二行如何也可以算作重复。

很遗憾,原始问题 (Finding duplicate values in multiple colums in a SQL table and count) 的解决方案不适用于 char

【问题讨论】:

    标签: sql sqlite union common-table-expression conditional-aggregation


    【解决方案1】:

    首先在 CTE 中使用 UNION ALL 对表进行规范化,以将 3 个名称中的每一个名称放在单独的行中。
    然后使用 ROW_NUMBER() 窗口函数,您可以按字母顺序排列 3 个名称,以便您可以按它们进行分组:

    WITH cte(id, name) AS (
      SELECT id, name1 FROM tablename
      UNION ALL
      SELECT id, name2 FROM tablename
      UNION ALL
      SELECT id, name3 FROM tablename
    )
    SELECT COUNT(*) count, name1, name2, name3
    FROM (
      SELECT id,
             MAX(CASE WHEN rn = 1 THEN name END) name1,
             MAX(CASE WHEN rn = 2 THEN name END) name2,
             MAX(CASE WHEN rn = 3 THEN name END) name3
      FROM (
        SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY name) rn
        FROM cte
      )
      GROUP BY id
    )
    GROUP BY name1, name2, name3
    HAVING COUNT(*) > 1;
    

    另一种方法,它使用与您之前的数值问题类似的逻辑,使用字符串函数REPLACE() 而不是窗口函数,但仅在每行中的 3 个名称不同时才有效:

    SELECT COUNT(*) count,
           MIN(name1, name2, name3) name_1,
           REPLACE(
             REPLACE(
               REPLACE(name1 || ',' || name2 || ',' || name3, MIN(name1, name2, name3), ''), 
               MAX(name1, name2, name3), ''), ',', ''
           ) name_2,
           MAX(name1, name2, name3) name_3
    FROM tablename 
    GROUP BY name_1, name_2, name_3 
    HAVING COUNT(*) > 1;
    

    请参阅demo

    【讨论】:

      【解决方案2】:

      不是特别漂亮,而是一种不同的方法来旋转列,然后将它们聚合为字符串并计算重复项。不幸的是,在 SQL Lite 中,group_concat 函数不能指定组内的任何顺序,这会导致另一个嵌套级别和 row_number。我想这是 SQL lite 的一部分!

      如果您想显示所有重复的变体,可以删除 Seq 和过滤条件。

      with cte as (
          select Duplicates, name1, name2, name3, 
            Row_Number() over(partition by Duplicates order by name1,name2,name3) Seq
          from (
            select count(*) over(partition by allnames) Duplicates, name1, name2, name3
            from t
            left join (
            select Id, group_concat(Dname) allNames
            from (
                select Id, Dname, row_number() over (partition by Id order by Dname) seq
                    from (
                        select id, name1 Dname from t union all
                        select id, name2 from t union all
                        select id, name3 from t
                    )x
             )x
           group by Id
           order by seq
           )d on d.id=t.id
         )d
      )
      select Duplicates, name1, name2, name3
      from cte
      where duplicates>1 and seq=1
      

      Demo Fiddle

      【讨论】:

        猜你喜欢
        • 2023-03-14
        • 2014-11-20
        • 1970-01-01
        • 2021-08-26
        • 1970-01-01
        • 2012-10-18
        • 1970-01-01
        • 1970-01-01
        • 2022-11-13
        相关资源
        最近更新 更多