@NeuraLink

Как составить sql запрос для вывода Новость дня?

Есть 2 таблицы : News и NewsLikes
`News` (
        `id` int(11) NOT NULL AUTO_INCREMENT,
        `title` varchar(80) CHARACTER SET utf8mb4 DEFAULT NULL,
        `description` varchar(600) CHARACTER SET utf8mb4 DEFAULT NULL,
        `imageIds` json DEFAULT NULL,
        `views` int(11) DEFAULT NULL,
        `created` datetime DEFAULT NULL,
        `userId` int(11) DEFAULT NULL,
        `status` tinyint(4) NOT NULL DEFAULT '0',
        `data` longblob,
        PRIMARY KEY (`id`),

`NewsLikes` (
        `id` int(11) NOT NULL AUTO_INCREMENT,
        `userId` int(11) DEFAULT NULL,
        `newsId` int(11) NOT NULL,
        `status` tinyint(4) NOT NULL DEFAULT '0',
        `created` datetime DEFAULT NULL,
        PRIMARY KEY (`id`),


Тестовые данные News
63f73b4060980920688719.png

Тестовые данные Likes
63f73b6708821832802398.png

Нужно написать такой sql запрос, чтобы результатом был такой вывод
63f73c25345aa715944194.png

На скриншоте выше выводятся строки за сегодня, вчера, позавчера и т.д (Т.е новость дня за сегодня, вчера и позавчера)
Нет дубликатов по полю created или likesCount.

В sql я не силен, поэтому чтобы получить такой вывод написал огромного монстра, но я уверен,что есть какое-то элегантное короткое решение, неравнодушных прошу помочь мне с написанием более короткого решения и более эффективного по скорости выполнения. Заранее спасибо за любую помощь, подсказку и наводку

P.S мой запрос
SELECT o.id, o.likes as likesCount, o.created, o.views, o.title, imageIds FROM
(SELECT o2.id, o2.created, o2.views, o2.title, o2.imageIds, IFNULL(o2.likes, 0) likes FROM
(SELECT max(id) as id FROM (SELECT id, created, likes FROM News wi LEFT JOIN (SELECT COUNT(NewsLikes.id) as likes,  `newsId` FROM  `NewsLikes` GROUP BY `newsId`) likesJoin ON wi.id = likesJoin.`newsId`) tl GROUP BY DATE_FORMAT(created, '%Y%m%d'), likes) tlg
JOIN (SELECT id,created,views,title, imageIds, IFNULL(likes,0) as likes FROM News o1 LEFT JOIN (SELECT COUNT(NewsLikes.id) as likes,  `newsId` FROM  `NewsLikes` GROUP BY `newsId`) likesJoin ON o1.id = likesJoin.`newsId`) o2 ON tlg.id = o2.id) o
LEFT JOIN
(SELECT o2.id, o2.created, o2.views, IFNULL(o2.likes, 0) likes FROM
(SELECT max(id) as id FROM (SELECT id, created, likes FROM News wi LEFT JOIN (SELECT COUNT(NewsLikes.id) as likes,  `newsId` FROM  `NewsLikes` GROUP BY `newsId`) likesJoin ON wi.id = likesJoin.`newsId`) tl GROUP BY DATE_FORMAT(created, '%Y%m%d'), likes) tlg
JOIN (SELECT id,created,views,title, IFNULL(likes,0) as likes FROM News o1 LEFT JOIN (SELECT COUNT(NewsLikes.id) as likes,  `newsId` FROM  `NewsLikes` GROUP BY `newsId`) likesJoin ON o1.id = likesJoin.`newsId`) o2 ON tlg.id = o2.id) b
ON DATE_FORMAT(o.created, '%Y%m%d') = DATE_FORMAT(b.created, '%Y%m%d')
AND  (o.likes < b.likes)
WHERE b.created IS NULL
ORDER BY o.created DESC
LIMIT  100 OFFSET 0
  • Вопрос задан
  • 93 просмотра
Решения вопроса 1
@NeuraLink Автор вопроса
Потратил ещё пару дней и есть ощущение, что лучше сделать невозможно, но если я не прав, предложите свой вариант, будет интересно взглянуть

SELECT dt.id, dt.created, dt.title, dt.imageIds, dt.views, dt.likesCount
FROM 
(SELECT id, created, title, views, imageIds, (SELECT COUNT(*) FROM NewsLikes AS w1 WHERE dt1.id = w1.newsId) as likesCount FROM `News` dt1) dt
LEFT JOIN (SELECT id, created, (SELECT COUNT(*) FROM `NewsLikes` AS `w1` WHERE b1.id = w1.newsId) as likesCount FROM `News` b1) b
ON DATE_FORMAT(dt.created, '%Y%m%d') = DATE_FORMAT(b.created, '%Y%m%d') 
AND (dt.likesCount < b.likesCount or (dt.likesCount = b.likesCount and dt.id < b.id))
WHERE b.id is NULL
ORDER BY dt.created DESC
LIMIT 5 OFFSET 0;
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
ThunderCat
@ThunderCat Куратор тега MySQL
{PHP, MySql, HTML, JS, CSS} developer
group by + count()
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы