У меня есть простой сценарий TableA, TableB и JoinTable, который объединяет TableA и TableB. Я хочу сохранить в TableA для каждой строки в TableA количество записей в JoinTable, которые имеют TableAId. Я могу выбрать его правильно следующим образом:
SELECT "Id", (SELECT COUNT(*) FROM "JoinTable" WHERE "JoinTable"."TableAId" = "TableA"."Id")
AS TOT FROM "TableA" LIMIT 100
Однако мне трудно написать запрос на обновление. Я хочу обновить TableA.JoinCount с помощью этого результата.
Вы можете использовать коррелированный подзапрос:
update tablea a
set tot = (
select count(*)
from jointable j
where t.tableaid = a.id
)
Это обновляет все строки tablea
количеством совпадений из jointable
; если совпадений нет, tot
устанавливается на 0
.
Однако я бы не рекомендовал хранить такую производную информацию. Хотя его можно легко инициализировать с помощью приведенного выше оператора, поддерживать его утомительно. Вскоре вы обнаружите, что создаете триггеры для каждой операции DML в таблице соединения (обновление, удаление, вставка). Вместо этого вы можете поместить информацию в представление:
create view viewa as
select id,
(select count(*) from jointable j where j.tableaid = a.id) as tot
from tablea a
Дополнительное примечание: как правило, не используйте идентификаторы в кавычках в Postgres. Это по этой ссылке подробнее.
Вы можете использовать группу по запросу в качестве источника для инструкции UPDATE:
update "TableA" a
set "JoinCount" = t.cnt
from (
select "TableAId" as id, count(*) as cnt
from "JoinTable"
group by "TableAId"
) t
WHERE t.id = a."Id"
Не имеет отношения к вашей проблеме, но: вам действительно следует избегать этих ужасных идентификаторов в кавычках. Они доставляют гораздо больше хлопот, чем того стоят. wiki.postgresql.org/wiki/…