Home > database >  Oracle SQL find columns with different values
Oracle SQL find columns with different values

Time:05-23

I have two tables A and B both with some millions rows and around one hundred columns.

I want to find which columns have different observations without the need of listing the names of all the columns.

For example, suppose column ID is the primary key in both tables. And that table A is

ID | col1 | col2
----------------
1  | 123  | 101
2  | 456  | 111

while table B is

ID | col1 | col2
----------------
1  | 123  | 101
2  | 456  | 222

The result of my query would be something about col2. I'm indifferent if a table based on observations form tabla A or B or whatever. What I would like in the query is to avoid to list all the columns since they are a lot. I am not interested in knowing the rows whose columns have different values, only the columns.

EDIT:

Consider these assumptions:

  • First, assume that the columns in the two tables have the same name. I would prefer something that works without this assumption but I'm more than ok with it.

  • Second, the columns of the tables are only numeric. Again, this is assumed to simplify.

Thanks!

CodePudding user response:

I got the answer from a colleague and I think it's worth posting it for future users. He used PL/SQL and a loop on the two tables TABLE_A and TABLE_B

SET SERVEROUTPUT ON SIZE 10000

DECLARE
    v_sql_text     VARCHAR2(300);
    n_contador     NUMBER;
    n_contador_2   NUMBER;
BEGIN
    FOR x IN (
        SELECT
            column_name
        FROM
            user_tab_columns
        WHERE
            table_name IN (
                'TABLE_A'
            )
    ) LOOP
        v_sql_text := 'SELECT /*  PARALLEL 32 */ count(1) FROM (SELECT DISTINCT('
                      || x.column_name
                      || ') FROM TABLE_A MINUS SELECT DISTINCT('
                      || x.column_name
                      || ') FROM TABLE_B)';

    EXECUTE IMMEDIATE v_sql_text
    INTO n_contador;
    v_sql_text := 'SELECT /*  PARALLEL 32 */ count(1) FROM (SELECT DISTINCT('
                  || x.column_name
                  || ') FROM TABLE_B MINUS SELECT DISTINCT('
                  || x.column_name
                  || ') FROM TABLE_A)';

    EXECUTE IMMEDIATE v_sql_text
    INTO n_contador_2;
    IF n_contador != 0 OR n_contador_2 != 0 THEN
        dbms_output.put_line(x.column_name || ' is different');
    END IF;

END LOOP;
END;
/
  • Related