Дубликаты в базе данных, помогите отредактировать мой запрос, чтобы отфильтровать их? - PullRequest
1 голос
/ 29 ноября 2011

Я только что закончил свою последнюю задачу по созданию RSS-канала с использованием PHP для извлечения данных из базы данных.

Я только что заметил, что у многих (если не у всех) этих предметов есть дубликаты, и я пытался понять, как получить только один из них.

У меня была мысль, что в моем цикле PHP я мог печатать только каждую вторую строку, чтобы иметь только один из каждого набора дубликатов, но в некоторых случаях есть 3 или 4 каждой статьи, так что каким-то образом это должно быть достигнуто запросом .

Запрос:

SELECT * 
FROM uk_newsreach_article t1
    INNER JOIN uk_newsreach_article_photo t2
        ON t1.id = t2.newsArticleID
    INNER JOIN uk_newsreach_photo t3
        ON t2.newsPhotoID = t3.id
ORDER BY t1.publishDate DESC;

Структуры таблиц:

uk_newsreach_article
--------------------
id | headline | extract | text | publishDate | ...

uk_newsreach_article_photo
--------------------------
id | newsArticleID | newsPhotoID

uk_newsreach_photo
------------------
id | htmlAlt | URL | height | width | ...

По тем или иным причинам существует множество дубликатов, и единственное, что действительно уникально среди каждого набора данных, - это uk_newsreach_article_photo.id, потому что хотя uk_newsreach_article_photo.newsArticleID и uk_newsreach_article_photo.newsPhotoID идентичны в наборе дубликатов, все, что мне нужно один из каждого набора, например,

Пример данных

id | newsArticleID | newsPhotoID
--------------------------------
 2 |     800482746 |     7044521
10 |     800482746 |     7044521
19 |     800482746 |     7044521
29 |     800482746 |     7044521
39 |     800482746 |     7044521
53 |     800482746 |     7044521
67 |     800482746 |     7044521

Я попытался вставить DISTINCT в запрос вместе с указанием нужных столбцов, но это не сработало.

Ответы [ 2 ]

1 голос
/ 29 ноября 2011

Как вы заметили, оператор DISTINCT будет возвращать каждый идентификатор. Вы могли бы использовать GROUP BY вместо этого.

Вам придется принять решение о том, id которого вы хотите сохранить. В этом примере я использовал MIN, но подойдет любая агрегатная функция.

Оператор SQL

SELECT MIN(t1.id), t2.newsArticleID, t2.newsPhotoID 
FROM uk_newsreach_article t1
    INNER JOIN uk_newsreach_article_photo t2
        ON t1.id = t2.newsArticleID
    INNER JOIN uk_newsreach_photo t3
        ON t2.newsPhotoID = t3.id
GROUP BY t2.newsArticleID, t2.newsPhotoID 
ORDER BY t1.publishDate DESC;

Ответственность

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

1 голос
/ 29 ноября 2011

group by все выбранные вами столбцы с HAVING COUNT(*) > 1 уничтожат все дубликаты следующим образом:

SELECT * 
FROM uk_newsreach_article t1
    INNER JOIN uk_newsreach_article_photo t2
      ON t1.id = t2.newsArticleID
    INNER JOIN uk_newsreach_photo t3
      ON t2.newsPhotoID = t3.id
GROUP BY  t1.id, t1.headline, t1.extract, t1.text, t1.publishDate,
          t2.id, t2.newsArticleID, t2.newsPhotoID,
          t3.id, t3.htmlAlt, t3.URL, t3.height, t3.width
HAVING  COUNT(*) > 1
ORDER BY t1.publishDate DESC;
...