Как получить данные по запросу, а если их нет, то использовать значение по умолчанию?

Элементарно, но только если не надо потом эти данные сразу же вставить, да все это еще и в одном запросе. Если бы не было нужно значение по умолчанию, то это тоже решалось бы легко подзапросом.

Можно подзапрос объединить через UNION с временной табличкой, содержащей строку по умолчанию, но тогда надо очень аккуратно выбрать правильное значение дополнительным условием (возможно, через флаги с их последующим вырезанием).

В итоге у меня родился такой монстр:

INSERT INTO stats(day, key, value)
SELECT '2022-08-04', key, COALESCE(stats."value", 0) 
FROM (VALUES(key)) as request(key)
LEFT JOIN stats on request.key=stats.key
WHERE (stats.value IS NULL) OR (stats."day" < '2022-08-04')
ORDER BY stats."day" DESC 
LIMIT 1
ON CONFLICT DO NOTHING

Тут производится LEFT JOIN с временной таблицей request, чтобы всегда получить хотя бы 1 строку, в которой будет либо null, либо ответ на запрос. Потом COALESCE(stats."value", 0) выбирает первое не-null значение.