用左连接求和案例

问题描述 投票:0回答:1

我想计算可用的

waves
(
LEFT OUT JOIN
)。我的问题是我在
LEFT OUTER JOIN
上还有另一个
invitations

这个想法是从同一个 SQL 请求中获取所有统计信息。统计数据来自

invitations
和统计数据来自
waves

一个事件有很多波 一个活动有很多邀请

CREATE TABLE public.events (
    id bigint NOT NULL,
    uuid uuid DEFAULT public.gen_random_uuid() NOT NULL
    name character varying NOT NULL
);
CREATE TABLE public.invitations (
    id bigint NOT NULL,
    uuid uuid DEFAULT public.gen_random_uuid() NOT NULL,
    event_id bigint NOT NULL
);
CREATE TABLE public.invitation_waves (
    id bigint NOT NULL,
    uuid uuid DEFAULT public.gen_random_uuid() NOT NULL,
    name character varying NOT NULL,
    wavable_type character varying,
    wavable_id bigint,
    scheduled_at timestamp(6) without time zone
);

我测试了2个选项

选项1

SELECT CAST(sum((case when (waves.id IS NOT NULL) then 1 else 0 end)) AS INTEGER) as total_waves
FROM "events"
         LEFT OUTER JOIN "waves" ON "waves"."wavable_type" = 'Event' AND
                                               "waves"."wavable_id" = "events"."id"
         LEFT OUTER JOIN "invitations" ON "invitations"."event_id" = "events"."id"
WHERE "events"."uuid" = 'XXX'
GROUP BY "events"."id"

-> 如果超过波数,它会给我创建的邀请数量

选项 2(带有
DISTINCT

SELECT CAST(sum(DISTINCT(case when (waves.id IS NOT NULL) then 1 else 0 end)) AS INTEGER) as total_waves
FROM "events"
         LEFT OUTER JOIN "waves" ON "waves"."wavable_type" = 'Event' AND
                                               "waves"."wavable_id" = "events"."id"
         LEFT OUTER JOIN "invitations" ON "invitations"."event_id" = "events"."id"
WHERE "events"."uuid" = 'XXX'
GROUP BY "events"."id"

-> 总是返回我

1
,我想,这是与请求匹配的事件数量(我已经使用 uuid 确定了范围)。

没有

DISTINCT
实际上是将正确的总和乘以波数。

通过

DISTINCT
将总和限制为波数。

选项 3(子选择)✅

我目前正在根据this答案尝试此选项。 它正在工作,但我担心

GROUP BY
LEFT OUTER JOIN
中选定的列之间的依赖关系。

SELECT CAST(sum((case
                     when (invitations.status = 4 or invitations.status = 5 or invitations.status = 6) then 1
                     else 0 end)) AS INTEGER) as total_validated,
       total_waves,
       waves_scheduled
FROM "events"
         LEFT OUTER JOIN "invitations" ON "invitations"."event_id" = "events"."id"
         LEFT OUTER JOIN (SELECT distinct on (wavable_id)
                                 wavable_id                                                                                      as event_id,
                                 CAST(sum((case when (invitation_waves.id IS NOT NULL) then 1 else 0 end)) AS INTEGER)           as total_waves,
                                 CAST(sum((case when (invitation_waves.scheduled_at IS NOT NULL) then 1 else 0 end)) AS INTEGER) as waves_scheduled
                          FROM invitation_waves
                          WHERE wavable_type = 'Event'
                          GROUP BY 1 
                          ORDER BY wavable_id) as "wave_stats" on "wave_stats"."event_id" = "events"."id"
WHERE "events"."uuid" = '1ee5ec72-6f3c-404c-871c-5c5724f6a1ed'
GROUP BY "events"."id", total_waves, waves_scheduled
sql postgresql left-join case
1个回答
0
投票

不太清楚您真正想要什么(没有样本数据和预期结果),但看起来您希望获得每个活动的邀请数量和/或波数和/或两者的总数。如果是这样,使用您的表格结构和我盲目猜测的数据,下面的代码可能可以帮助您获得所需的内容:

Select     e.id as event_id, e.name as event_name,
           Count(Distinct i.id) as total_event_invitations,
           Count(iw.id) as total_event_waves, 
           Count(Distinct i.id) + Count(iw.id) as total_event_invitations_and_waves
From       events e
Left Join  invitations i ON(i.event_id = e.id)
Left Join  invitation_waves iw ON(iw.wavable_id = e.id)
Where      wavable_type = 'Event'
Group By   e.id, e.name
Order By   e.id
/*
event_id  event_name  total_event_invitations  total_event_waves  total_event_invitations_and_waves
--------  ----------  -----------------------  -----------------  ---------------------------------
       1  event 1                           2                  4                                  6
       2  event 2                           3                 12                                 15      */

请参阅此处的小提琴

© www.soinside.com 2019 - 2024. All rights reserved.