Почему при использовании «select count» получается меньше строк дублирования, чем в реальном числе - PullRequest
0 голосов
/ 03 марта 2020

У меня есть эта таблица с 6735 строками, например:

id title source_link date_created processed topic_id date_create_unix 

. В ней несколько строк с повторяющимся «заголовком», некоторые строки дублируются 2 раза, некоторые 3 или 4 раза. Поэтому мне нужно удалить лишние строки, но для этого мне нужно сначала удалить строки в таблице ссылок (иначе это не позволит мне удалить из-за ограничений внешнего ключа). Поэтому мне нужно извлечь идентификатор дополнительных строк. Я могу получить идентификатор (я) строк, которые я хочу сохранить:

    SELECT t1.id FROM Data.rss_table t1
INNER JOIN Data.rss_table t2 
WHERE 
    t1.id > t2.id AND 
    t1.title = t2.title

это дает мне 1350 строк.

Тогда, если я использую это:

SELECT t1.id FROM Data.rss_table t1
INNER JOIN Data.rss_table t2 
WHERE  
    t1.id != t2.id
AND
    t1.title = t2.title

это даст мне 2700 строк. Итак, я знаю, что он не содержит все идентификаторы дублирования, потому что некоторые строки дублируются более чем в два раза, поэтому число должно быть больше 1350 x 2 (= 2700).

Так что я надеюсь, что это даст мне все Дублирование:

SELECT * FROM Data.rss_table GROUP BY title HAVING COUNT(title) > 1

, но возвращает только 944 строки. Я очень удивлен этим результатом, он даже меньше, чем результат из 2-го запроса выше (2700). Хотя я думал, что должны дать все строки с дублированным заголовком, поэтому число должно быть больше. Как это объяснить, и как я могу заархивировать свои результаты?

Примечание. Если во втором запросе указаны все идентификаторы строк дублирования, я могу удалить таблицу ссылок по этому запросу:

Delete from Data.rss_source_link where rss_id in (
Select SetA.id from (SELECT t1.id FROM Data.rss_table t1
INNER JOIN Data.rss_table t2 
WHERE  
    t1.id != t2.id
AND
    t1.title = t2.title) as SetA
left join 

(SELECT t1.id FROM Data.rss_table t1
INNER JOIN Data.rss_table t2 
WHERE 
    t1.id > t2.id AND 
    t1.title = t2.title) as SetB
On SetB.id = null
);

1 Ответ

0 голосов
/ 03 марта 2020

Легко создать эффект, который вы видите

drop table if exists t,t1;
create table t(id int, title varchar(3));
create table t1(id int,title varchar(3));

insert into t values
(1,'aaa'),(1,'aaa'),(2,'aaa');

insert into t1 values
(1,'aaa'),(1,'aaa'),(2,'aaa');

SELECT t1.id ,t2.id
FROM t t1
INNER JOIN t1 t2
WHERE 
    t1.id > t2.id AND 
    t1.title = t2.title;

+------+------+
| id   | id   |
+------+------+
|    2 |    1 |
|    2 |    1 |
+------+------+
2 rows in set (0.00 sec)

SELECT t1.id t2.id
FROM t t1
INNER JOIN t1 t2 
WHERE  
    t1.id != t2.id
AND
    t1.title = t2.title;

+------+------+
| id   | id   |
+------+------+
|    2 |    1 |
|    2 |    1 |
|    1 |    2 |
|    1 |    2 |
+------+------+
4 rows in set (0.00 sec)

SELECT * FROM t GROUP BY title HAVING COUNT(title) > 1;

+------+-------+
| id   | title |
+------+-------+
|    1 | aaa   |
+------+-------+
1 row in set (0.00 sec)

Так что вы подразумеваете под дубликатом - это id + title или просто title?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...