CASE
для двух категорий можно решить для свопинга категорий, например как-то так:SELECT id, title, description, source, category, published_on
FROM (
SELECT *, (
CASE WHEN (select json_agg(t.cat ORDER BY t.cat ASC) ->> 0 = ('["c2", "c1"]'::json) ->> 0
from (select json_array_elements_text('["c2", "c1"]') as cat) t)
THEN rank() OVER (PARTITION BY source ORDER BY category, published_on DESC)
ELSE
rank() OVER (PARTITION BY source ORDER BY category DESC, published_on DESC)
END
)
FROM app_news
WHERE category IN ('c1', 'c2')
-- next part
where
во временных таблицах t1 и t2, и категорию в конструкции NOT EXISTS
в t3. Если добавиться условие для третьей и т.д. категорий, то да, там количество кода значительно увеличится :). OVER (PARTITION BY "source" ORDER BY category, published_on DESC)
OVER (PARTITION BY "source" ORDER BY category DESC, published_on DESC)