【问题标题】:count of duplicate records by passing dynamic table name and colum names通过传递动态表名和列名来计算重复记录
【发布时间】:2020-08-04 19:46:29
【问题描述】:

感谢您提前提供的所有帮助。

我需要查找所有表(超过 100 个)中是否存在重复的退出。

我知道按表查找重复项的 SQL,但无论如何我们可以传递 colu 和 table 作为动态运行 sql。

表名和key col需要动态传递

step1 : SQL 获取所有表名和关联的键 col step2:运行重复查询 选择 col1,col2,....col5 计数(1) 从 schema.tablename 按 col1,col2...col 5 分组 有 count(1) > 1

请帮助我避免手动通过 cols 和 tablenames 手动运行的手动操作。

谢谢

【问题讨论】:

    标签: sql oracle oracle11g duplicates sql-delete


    【解决方案1】:

    您可以使用*_TAB_COLUMNS 视图和LISTAGG 构建您的SQL 脚本。

    例如:

    select 
      'select '||listagg(column_name, ',') within group (order by column_name)||
      ' from '||table_name||' 
       group by '||listagg(column_name, ',') within group (order by column_name)||' 
       having count(*) >1 ' str
    from user_tab_columns where table_name = 'EMPLOYEES'
    group by table_name;
    

    HR 模式中EMPLOYEES 表的上述查询的输出(当然格式化了 SQL)

    SELECT
        commission_pct,
        department_id,
        email,
        employee_id,
        first_name,
        hire_date,
        job_id,
        last_name,
        manager_id,
        phone_number,
        salary
    FROM
        employees
    GROUP BY
        commission_pct,
        department_id,
        email,
        employee_id,
        first_name,
        hire_date,
        job_id,
        last_name,
        manager_id,
        phone_number,
        salary
    HAVING
        COUNT(*) > 1;
    

    要遍历架构中的所有表并为所有表生成它,您可以执行以下操作:

    DECLARE
      TABLE_COLUMNS VARCHAR2(10000);
      DELETE_STATEMENT VARCHAR2(10000);
      CURSOR ALL_MY_TABLES IS (SELECT TABLE_NAME FROM USER_TABLES);
    BEGIN
      FOR MY_TABLE IN ALL_MY_TABLES 
      LOOP
        -- prepare the list of columns
        SELECT LISTAGG(COLUMN_NAME, ',') WITHIN GROUP (ORDER BY 1) INTO TABLE_COLUMNS FROM 
            USER_TAB_COLUMNS WHERE TABLE_NAME = 'YOUR_TABLE_NAME';
        -- prepare the delete statements
        DELETE_STATEMENT := 'DELETE FROM ' || YOUR_TABLE_NAME || ' WHERE ROWID NOT IN 
            (SELECT MIN(ROWID) FROM ' || YOUR_TABLE_NAME 
             || ' GROUP BY ' || TABLE_COLUMNS ||');';
        EXECUTE IMMEDIATE DELETE_STATEMENT;
        -- output of all delete statements in loop
        DBMS_OUTPUT.PUT_LINE(DELETE_STATEMENT);
      END LOOP;
    END;
    /
    

    【讨论】:

    • 不确定如何动态传递,因为我不熟悉 pl sql 脚本。我可以更详细的信息吗
    • 您拥有答案中所要求的一切。只是通过它来理解。这只是复制粘贴和执行它的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    • 2013-08-12
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多