Разработка @ ответа GMB
Ваш запрос:
$_30daysago = strtotime('-30 days');
SELECT * FROM
(
SELECT users.username, news_id
FROM users inner join news_viewed ON
users.username = news_viewed.username and users.status='active'
UNION
SELECT news_viewed.username, post_time
FROM news_viewed inner join news ON
news_viewed.newsid = news.newsid and news.post_time>'$_30daysago'
) as JoinedTable
говорит:
получить всех активных пользователей с новостями, которые они прочитали (внутреннийприсоединиться)
SELECT users.username, news_id
FROM users inner join news_viewed ON
users.username = news_viewed.username and users.status='active'
и добавить все новости тем пользователям, которые их прочитали за последние 30 дней (внутреннее объединение снова)
SELECT news_viewed.username, post_time
FROM news_viewed inner join news ON
news_viewed.newsid = news.newsid and news.post_time>'$_30daysago'
Это фактически вызывает все кортежи из news_viewed
минус те, в которых пользователь не активен, а новый старше 30 дней.
однако, учитывая использование внутреннего соединения, вы приноситемного повторяющихся записей
1.- Результаты первого запроса, где новый менее 30 дней
2.- Результаты второго запроса, где пользователь активен
, поскольку вы используете UNION, а не UNION ALL, вы неявно запрашиваете SELECT DISTINCT, но поля разные (нет смысла отображать newsid, а затем post_time в том же поле) plus, у вас есть опечатка в имени поля, которая не является news_id
Вы должны смотреть на это с другой стороны. Потенциальные комбинации составляют для сценария, где каждый пользователь прочитал каждое новое. Таким образом, вы получаете эту вселенную за основу (количество пользователей, умноженное на количество новостей), а затем
1 - удаляете неактивных пользователей
2 - удаляете новости старше 30 дней
3- удалите кортежи, которые не связаны в таблице news_viewed
SELECT users.username, news.newsid
FROM users
JOIN news
ON users.status='active' -- removes inactive users
AND news.post_time>'$_30daysago' -- removes older news
LEFT JOIN
news_viewed nv USING (username, newsid)
WHERE nv.nvid IS NULL -- removes unrelated entries