How to get rid of the php wrapping on this sql que

2019-08-25 03:12发布

I have two tables. One is production table with posts and other is the collection of posts's views.

Once a hour, all post views get grouped together and main production table gets updated. And post's views table gets truncated.

My objective is to get this function into pure SQL, so I could run it inside database engine as scheduled event.

SQL is my weakest point, and I can make it work with SELECT being inside one UPDATE. But if there are two UPDATE queries, then I need some sort of variable.

This is where I started:

<?  
# find new views grouped together:
$find_views = db::query("SELECT `post_id`, COUNT(*) AS `post_views` FROM `posts__views` WHERE `date_imported` IS NULL GROUP BY `post_id`;");
while ($view = db::fetch($find_views)) {

    # Update the main production tables views_count column:
    db::query("UPDATE `posts` SET `views_count` = views_count + {$view['post_views']} WHERE `id` = '{$view['post_id']}';");

    # Update the post's views table... but why does it actually needs this update hmm..
    db::query("UPDATE `posts__views` SET `date_imported` = NOW() WHERE `date_imported` IS NULL AND `post_id` = '{$view['post_id']}';");
}

# Trunkate post's views:
db::query("TRUNCATE TABLE `posts__views`;");

I realised, that I can make the code right away optimised, by removing the second UPDATE. And I think I can also remove date_imported completely, as all views get parsed and then truncated.

Which means, that I could most likely do UPDATE ... WHERE (SELECT ...). Only problem is that, I know how to do UPDATE with SELECT in it, for one variable. But since I have $view['post_views'] and $view['post_id'] in the same UPDATE query, then I am hopeless lost.

EDIT
This is not a duplicate to:
MySQL: UPDATE table with COUNT from another table?
As there is no truncate there. It works on the basis, that views table stays as is, with old views in place to calculate each time. I truncate the table, so rows from main table, with no new views is being SET to 0.

EDIT 2
So I have gotten this far:

UPDATE `posts` SET `views_count` = views_count + (SELECT COUNT(`id`) AS `views` FROM `posts__views` WHERE `post_id` = `posts`.`id` GROUP BY `post_id` HAVING COUNT(`id`) > 0)

No thanks to marking this question duplicate. As I cannot find any method to make sure, that other rows, that do not have views do not get set to 0. So the innner-SELECT should come out, and outer-UPDATE should have WHERE clause. In theory like this (but this doesnt' look optimised at all):

UPDATE `posts` SET `views_count` = views_count + (SELECT COUNT(`id`) AS `views` FROM `posts__views` WHERE `post_id` = `posts`.`id` GROUP BY `post_id` HAVING COUNT(`id`) > 0) WHERE (SELECT COUNT(`id`) AS `views` FROM `posts__views` WHERE `post_id` = `posts`.`id` GROUP BY `post_id` HAVING COUNT(`id`) > 0) > 0;

0条回答
登录 后发表回答