Мне нужно найти Подписки, а затем проверить каждую Подписку, есть ли какие-либо Уведомления, связанные с этой Подпиской, за последние n часов, а если нет, возьмите эту Подписку
Я придумал два решения, но я не совсем доволен ими обоими. Может ли кто-нибудь помочь сделать это наиболее эффективно?
Решение 1:
SELECT
"Subscription"."id",
FROM
"Subscriptions" AS "Subscription"
WHERE
"Subscription"."UserId" = 2
AND "Subscription"."isActive" = TRUE
AND "Subscription"."FeedId" = 35
AND NOT EXISTS (
SELECT* FROM "Notifications" AS "Notification"
WHERE
"Notification"."SubscriptionId" = "Subscription"."id"
AND (("Notification"."createdAt" > now() - interval '1 hours' AND "Notification"."CreativeId" = 70)
OR ("Notification"."createdAt" > now() - interval '6 hours' AND "Notification"."FeedId" = 35))
)
GROUP BY
"Subscription"."id"
LIMIT 15000 OFFSET 0;
Решение 2:
SELECT
"Subscription"."id",
FROM
"Subscriptions" AS "Subscription"
LEFT OUTER JOIN "Notifications" AS "Notification" ON "Subscription"."id" = "Notification"."SubscriptionId" AND "Notification"."createdAt" > now()::date - interval '6 hours'
AND ("Notification"."FeedId" = 35 OR "Notification"."CreativeId" = 70)
WHERE
"Subscription"."UserId" = 2
AND "Subscription"."isActive" = TRUE
AND "Subscription"."FeedId" =35
GROUP BY
"Subscription"."id"
HAVING
COUNT("Notification"."SubscriptionId") FILTER (WHERE "Notification"."FeedId" = 35
AND "Notification"."createdAt" > now() - interval '6 hours') < 1
AND
COUNT("Notification"."SubscriptionId") FILTER (WHERE "Notification"."CreativeId" = 70
AND "Notification"."createdAt" > now() - interval '1 hours') < 1
LIMIT 15000 OFFSET 0;
Когда я делаю и то, и другое в TablePlus, первое кажется чтобы сделать немного лучше, но когда я тестирую их на своем бэкэнде, второй выигрывает разительно. Пытаюсь понять почему, но раз уж через пару дней начал работать с чистым SQL а go, решил тут спросить