#mysql #join #left-join
#mysql #Присоединиться #левое соединение
Вопрос:
У меня есть следующий запрос, который должен выбирать все статьи из article_new, которые либо А) отсутствуют в ArticlesInCategories_New, либо Б) в нем, но не имеют CategoryID = 7, 8, 9, 10 или 11.
Удалив строки Category !=, я определил, что проблема заключается (по крайней мере) в том, что article_new не выбирает все из article_new, которого нет в ArticlesInCategories_New . Я все еще не совсем понимаю GroupBy, но я основывался на других вопросах, я попробовал GroupBy Articles_New.articleId , и это ничего не изменило.
SELECT
DISTINCT Articles_New.ArticleID,
DATE_FORMAT(Articles_New.PublicationDate, '%c/%e/%Y') AS ReleaseDate,
Articles_New.Title,
Articles_New.Type,
Articles_New.URL
FROM
Articles_New
LEFT JOIN ArticlesInCategories_New
ON ArticlesInCategories_New.ArticleID = Articles_New.ArticleID
WHERE
PublicationDate >= DATE_SUB(CURDATE(), INTERVAL 2 MONTH) AND
PublicationDate <= CURDATE() AND
Articles_New.Public = '1'
AND ArticlesInCategories_New.CategoryID != '7'
AND ArticlesInCategories_New.CategoryID != '8'
AND ArticlesInCategories_New.CategoryID != '9'
AND ArticlesInCategories_New.CategoryID != '10'
AND ArticlesInCategories_New.CategoryID != '11'
ORDER BY
Articles_New.PublicationDate DESC,
Articles_New.ArticleID DESC
Ответ №1:
Вам нужны все строки, которые либо:
А) отсутствуют в ArticlesInCategories_New
Б) в ArticlesInCategories_New, но не имеют CategoryID = 7, 8, 9, 10 или 11.
SELECT DISTINCT
Articles_New.ArticleID,
DATE_FORMAT(Articles_New.PublicationDate, '%c/%e/%Y') AS ReleaseDate,
Articles_New.Title,
Articles_New.Type,
Articles_New.URL
FROM
Articles_New
LEFT JOIN ArticlesInCategories_New
ON ArticlesInCategories_New.ArticleID = Articles_New.ArticleID
WHERE
(
ArticlesInCategories_New.ArticleID IS NOT NULL AND
PublicationDate BETWEEN DATE_SUB(CURDATE(), INTERVAL 2 MONTH) AND CURDATE()
AND Articles_New.Public = '1'
AND ArticlesInCategories_New.CategoryID NOT IN ('7','8','9','10','11')
)
OR
(
ArticlesInCategories_New.ArticleID IS NULL
)
ORDER BY
Articles_New.PublicationDate DESC,
Articles_New.ArticleID DESC
Комментарии:
1. Работает отлично, спасибо! Я не понимаю, хотя зачем
ArticlesInCategories_New.ArticleID IS NULL
это требуется. Разве это не цель использования aLEFT JOIN
?2. @John, у тебя есть 2 условия.
is null
Тест проверяет первое условие: он возвращает все строки, для которых нет совпадений . Другой тест предназначен для второго условия. Там я добавилis not null
, потому что вы заявили, что должно быть совпадение.3. @John, левое соединение возвращает все строки в левой таблице (article_new), а данные для таблицы этих строк совпадают в правой таблице (ArticlesInCategories_New) {null для тех, которые не совпадают}
Ответ №2:
Вы описываете два набора статей, которые вы хотите, all the articles from Articles_New
которые удовлетворяют одному из следующих:
- А) не в
ArticlesInCategories_New
- Б) in
ArticlesInCategories_New
, но не имеютCategoryID
= 7, 8, 9, 10 или 11.
Вы могли бы упростить этот сложный запрос, найдя эти два набора по отдельности, а затем объединив их с a UNION
. Это позволит вам тестировать и отлаживать каждый из запросов отдельно.
Комментарии:
1. Без тестирования похоже, что ваш ответ сработает. Но действительно ли написание двух операторов и объединение их с помощью ‘UNION’ упрощает это? Это кажется таким же сложным
2. Мнения могут различаться, но я думаю, что важным преимуществом является то, что вы можете
test and debug each of the queries separately
.