2016-11-26 3 views
3

Я хочу, чтобы мой форум Flarum обновил свои записи обсуждения после ручного вмешательства в базу данных. (Flarum все еще в бета-версии и до сих пор не хватает многих функций, делать исправления ошибок вручную не так уж редко.) Мне удалось составить следующий запрос, который делает то, что я хотел:Упростите несколько подзапросов в инструкции UPDATE

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); 

, но это выглядит довольно некрасиво. Я уверен, что есть способ написать ту же логику гораздо более кратким и эффективным способом, но я не знаю, как это сделать. Может ли кто-нибудь сказать мне, как устранить эти почти дублированные подзапросы?

Указанных выше определение таблицы выглядит следующим образом (причем некоторые детали опущены):

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 использует MySQL в качестве своей основной системы хранения данных, так что MySQL-конкретное решение будет в порядке. Однако было бы замечательно, если кто-то знает, как решить проблему в ANSI-SQL.

+0

Там нет ярлыка на то, что вы хотите. Вы должны сделать это, я думаю. Но мне хотелось бы узнать, может ли это случиться. – FallAndLearn

ответ

1

вы могли бы использовать внутреннее соединение и использовать максимум и минимум для первого и последнего

UPDATE discussions as d 
INNER JOIN posts as p on d.id = p.discussion_id 
SET d.start_time = min(p.time), 
    d.last_time = max(p.time), 
    d.comments_count = count(*), 
    d.participants_count = count(DISTINCT p.user_id) , 
    d.start_post_id = min(p.id), 
    d.start_user_id = min(p.user_id ), 
    d.last_post_id = max( p.id), 
    d.last_post_number = max(p.number), 
    d.last_user_id = max(p.user_id ), 
    d.comments_count = sum(case when p.type = 'comment' then 1 else 0) 
GROUP BY d.id 
+0

Я думаю, что это не сработает по своему желанию. Во-первых, вы меняете схему таблиц «обсуждение» – FallAndLearn

+0

я изменил ничто .. я просто реорганизовал запрос, используя .. sql features .. like required by OP – scaisEdge

+0

Выглядит многообещающе! Но я не могу понять, как 'd.last_post_id = min (d.last_post_id)' будет работать здесь. Проблемы с MySQL * Сообщение об ошибке «Ошибка: неверное использование групповой функции» *. – firegurafiku

Смежные вопросы