Группировка пустых значений в соответствии с полями без значений для проверки дубликатов в SQL - PullRequest
0 голосов
/ 28 апреля 2020

Я пытаюсь улучшить / оптимизировать мой запрос для проверки дубликатов в моей таблице TABLE1. Основное требование состоит в том, чтобы рассматривать нулевое значение как подстановочный знак.

Итак, с учетом приведенной ниже таблицы:

enter image description here

Рассматривая пустые поля как подстановочный знак, где, например, 'A' = null, имеет значение true. Ожидаемый результат - детали записи каждой записи в группе, а также с идентификатором группы, который является id и id1 в самой правой части таблицы:

enter image description here

Что уже достигнуто с помощью этого запроса:

WITH CTE
    AS (SELECT t1.id, t2.id as id1 FROM TABLE1 t1
             INNER JOIN TABLE1 t2 
                ON (t1.column1 = t2.column1 OR (t1.column1 IS NULL OR t2.column1 IS NULL))
                AND (t1.column2 = t2.column2 OR (t1.column2 IS NULL OR t2.column2 IS NULL))
                AND (t1.column3 = t2.column3 OR (t1.column3 IS NULL OR t2.column3 IS NULL))
                AND (t1.column4 = t2.column4 OR (t1.column4 IS NULL OR t2.column4 IS NULL))
                AND (t1.column5 = t2.column5 OR (t1.column5 IS NULL OR t2.column5 IS NULL))
                AND (t1.column6 = t2.column6 OR (t1.column6 IS NULL OR t2.column6 IS NULL))
        WHERE t2.id > t1.id)
    SELECT *
    FROM TABLE1 t1
        INNER JOIN CTE C
        ON t1.id = c.id
        OR t1.id = c.id1

Я также использую индекс, содержащий Id, column1, column2, column3, column4, column5 и column6. Для небольшой таблицы запрос выполняется нормально, но когда я запускаю его с миллионами данных, он выполняется вечно.

Я пытался использовать соединения и isnull, но, похоже, это не имело значения.

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Вы можете рассмотреть следующее (в MySQL, если это имеет значение) ...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,col1 CHAR(1) NULL
,col2 CHAR(1) NULL
,col3 CHAR(1) NULL
);

 INSERT INTO my_table VALUES
 (1,'A','B',NULL),
 (2,'A',NULL,'C');

 SELECT * FROM my_table;
+----+------+------+------+
| id | col1 | col2 | col3 |
+----+------+------+------+
|  1 | A    | B    | NULL |
|  2 | A    | NULL | C    |
+----+------+------+------+
2 rows in set (0.01 sec)

SELECT a.*
     , b.*
  FROM 
     ( SELECT id, 'c1' col, col1 val FROM my_table
        UNION ALL
       SELECT id, 'c2', col2 FROM my_table
        UNION ALL
       SELECT id, 'c3', col3 FROM my_table
     ) a
  JOIN
     ( SELECT id, 'c1' col, col1 val FROM my_table
        UNION ALL
       SELECT id, 'c2', col2 FROM my_table
        UNION ALL
       SELECT id, 'c3', col3 FROM my_table
     ) b
    ON b.id > a.id
   AND b.col = a.col
   AND (b.val = a.val OR b.val IS NULL or a.val IS NULL);

   +----+-----+------+----+-----+------+
   | id | col | val  | id | col | val  |
   +----+-----+------+----+-----+------+
   |  1 | c1  | A    |  2 | c1  | A    |
   |  1 | c2  | B    |  2 | c2  | NULL |
   |  1 | c3  | NULL |  2 | c3  | C    |
   +----+-----+------+----+-----+------+
0 голосов
/ 28 апреля 2020

Код, который вы используете, несовместим для использования больших данных. Я бы предложил упростить ваш код.

...