I want to make my Flarum forum update its discussion records after manual intervention into the database. (Flarum is still in beta and still lacks many features, so fixing things manually isn't that uncommon.) I managed to compose the following query which does what I wanted:
UPDATE discussions as d SET
d.start_time =
(SELECT min(p.time) FROM posts as p
WHERE p.discussion_id = d.id),
d.last_time =
(SELECT max(p.time) FROM posts as p
WHERE p.discussion_id = d.id),
d.comments_count =
(SELECT count(*) FROM posts as p
WHERE p.discussion_id = d.id AND p.type = 'comment'),
d.participants_count =
(SELECT count(DISTINCT p.user_id) FROM posts as p
WHERE p.discussion_id = d.id),
d.start_post_id =
(SELECT p.id FROM posts as p
WHERE p.discussion_id = d.id
ORDER BY p.number ASC LIMIT 1),
d.start_user_id =
(SELECT p.user_id FROM posts as p
WHERE p.discussion_id = d.id
ORDER BY p.number ASC LIMIT 1),
d.last_post_id =
(SELECT p.id FROM posts as p
WHERE p.discussion_id = d.id
ORDER BY p.number DESC LIMIT 1),
d.last_post_number =
(SELECT p.number FROM posts as p
WHERE p.discussion_id = d.id
ORDER BY p.number DESC LIMIT 1),
d.last_user_id =
(SELECT p.user_id FROM posts as p
WHERE p.discussion_id = d.id
ORDER BY p.number DESC LIMIT 1);
but it looks pretty ugly. I'm sure there is a way to write the same logic in a much more concise and efficient way, but I'm not really into SQL to know how to do it. Could someone tell me how to eliminate these almost duplicated subqueries?
The above mentioned tables definition is the following (with some details omitted):
CREATE TABLE discussions (
id int unsigned NOT NULL AUTO_INCREMENT,
title varchar(200) NOT NULL,
comments_count int(10) unsigned NOT NULL DEFAULT '0',
participants_count int(10) unsigned NOT NULL DEFAULT '0',
number_index int(10) unsigned NOT NULL DEFAULT '0',
start_time datetime NOT NULL,
start_user_id int(10) unsigned DEFAULT NULL,
start_post_id int(10) unsigned DEFAULT NULL,
last_time datetime DEFAULT NULL,
last_user_id int(10) unsigned DEFAULT NULL,
last_post_id int(10) unsigned DEFAULT NULL,
last_post_number int(10) unsigned DEFAULT NULL,
... );
CREATE TABLE posts (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
discussion_id int(10) unsigned NOT NULL,
number int(10) unsigned DEFAULT NULL,
time datetime NOT NULL,
user_id int(10) unsigned DEFAULT NULL,
type varchar(100) DEFAULT NULL,
... );
Flarum uses MySQL as its primary storage backend, so MySQL-specific solution would be fine. However, it would be great if someone knows how to solve the problem in ANSI-SQL.