Сегодня я выяснил, что немного плаваю в конструировании сложных SQL запросов. Вот задача, которая у меня возникла: надо посчитать количество постов в рубрике/метки после публикации/редактирования поста. То, что я писал ранее про ненужность таблицы пар пост/метка явная глупость - отчего то у меня тогда выскочило из внимания тот факт, что рубрика может иметь сотни постов, и загонять числа id постов в строку глупо. Вариант со строкой id хорош только для постов - так оно и будет, иными словами уже готовый результат выборки из таблицы пар пост/тег. Для рубрик это будет только во вред.

И так на входе имеем postid - id поста который был добавлен/отредактирован, и список id рубрик/меток этого поста. Надо обновить таблицу рубрик/меток и таблицу пар. Для таблицы пар можно сделать два запроса - вначале удалить все пары с postid, а потом вставить новые. Как вариант можно удалить отсутствующие и добавить новые, но для этого потребуется хитрожопый запрос для вычисления еще недобавленных, поэтому пока остановился на удалить все, а потом добавить все.

Значит, таблицу пар обновил, остаться обновить количество опубликованных постов в таблице рубрик/меток. Строго говоря нет особой необходимости хранить то значение, но поскольку для его вычисления требуются вложенные, и следовательно ресурсоемкие запросы, то однозначно лучше иметь уже готовый результат выборки. На словах описать запрос легко: обновить количество постов, в рубриках которые были удалены/добавлены в таблице пар. Если бы все посты были бы только опубликованные (то есть не существовали черновики и отложенные), то запрос выглядел примерно так:


update tagstable set itemscount = postscount
(select count(post) as postscount from tagsitemstable where tag in ($items) group by post)
where id in ($items)

где post и tag - поля в таблице пар tagsitemstable. Но этот запрос на самом деле безполезен, так как требуется отсеч черновики. Вероятно следует модифицировать подзапрос следующим образом:


select count(post) as postscount from tagsitemstable, poststable where tag in ($items) and poststable.id = post and poststable.status = 'published group by post

Но вот уверености в правильности такого запроса нет. По существу должно выполнится три запроса: выборка из таблицы пар только тех постов, которые опубликованы (это два запроса на двух таблицах), и результаты писать в - третий запрос. Дело усугубляется тем, что в голову лезут запросы наподобие следующего:


select m.id,count(*)  from m left join s using(id) group by m.id

Который мне кажется более простым, но менее понятным - все же намного проще думать вложенными select, чем join using group by...