Sql 统计用户尚未联系的组织

Sql 统计用户尚未联系的组织,sql,postgresql,count,left-join,inner-join,Sql,Postgresql,Count,Left Join,Inner Join,我是PostgreSQL的新手。我在模式中创建了以下表: 用户表: CREATE TABLE public.users ( user_id integer NOT NULL DEFAULT nextval('users_user_id_seq'::regclass), first_name character varying(90) COLLATE pg_catalog."default" NOT NULL, last_name character v

我是PostgreSQL的新手。我在模式中创建了以下表:

用户表:

CREATE TABLE public.users
(
    user_id integer NOT NULL DEFAULT nextval('users_user_id_seq'::regclass),
    first_name character varying(90) COLLATE pg_catalog."default" NOT NULL,
    last_name character varying(90) COLLATE pg_catalog."default" NOT NULL,
    email citext COLLATE pg_catalog."default" NOT NULL,
    user_password character varying(90) COLLATE pg_catalog."default" NOT NULL,
    bt_id integer,
    reset_password_token character varying COLLATE pg_catalog."default",
    bstage_id integer,
    CONSTRAINT users_pkey PRIMARY KEY (user_id),
    CONSTRAINT users_email_key UNIQUE (email),
    CONSTRAINT bstage_id FOREIGN KEY (bstage_id)
        REFERENCES public.business_stage (bstage_id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE CASCADE,
    CONSTRAINT bt_id FOREIGN KEY (bt_id)
        REFERENCES public.business_type (bt_id) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE CASCADE
        NOT VALID
)
WITH (
    OIDS = FALSE
)
组织机构表:

CREATE TABLE public.organization
(
    org_id integer NOT NULL DEFAULT nextval('organization_org_id_seq'::regclass),
    name character varying(90) COLLATE pg_catalog."default" NOT NULL,
    description character varying(90) COLLATE pg_catalog."default" NOT NULL,
    email citext COLLATE pg_catalog."default" NOT NULL,
    phone_number character varying(11) COLLATE pg_catalog."default" NOT NULL,
    bt_id integer NOT NULL,
    bs_id integer NOT NULL,
    is_active boolean NOT NULL,
    org_link character varying COLLATE pg_catalog."default",
    CONSTRAINT organization_pkey PRIMARY KEY (org_id),
    CONSTRAINT bs_id FOREIGN KEY (bs_id)
        REFERENCES public.business_step (bs_id) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE CASCADE
        NOT VALID,
    CONSTRAINT bt_id FOREIGN KEY (bt_id)
        REFERENCES public.business_type (bt_id) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE CASCADE
        NOT VALID
)
WITH (
    OIDS = FALSE
)
最后 组织机构评级表:

CREATE TABLE public.organization_rating
(
    rating integer NOT NULL,
    user_id integer NOT NULL,
    organization_id integer NOT NULL,
    rating_comment character varying(255) COLLATE pg_catalog."default",
    CONSTRAINT organization_rating_pkey PRIMARY KEY (user_id, organization_id),
    CONSTRAINT user_id FOREIGN KEY (user_id)
        REFERENCES public.users (user_id) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE CASCADE,
    CONSTRAINT stars CHECK (rating >= 1 AND rating < 5)
)
WITH (
    OIDS = FALSE
)
我如何计算此用户尚未联系的组织,以及已联系的与仍要联系的组织的百分比


如果你也能给我介绍一些网站,帮助我了解更多的PostgreSQL和不同的功能,我将不胜感激。提前谢谢你

您可以
交叉连接
用户和组织以获得所有可能的组合,然后将桥接表与
左连接
。最后一步是条件聚合:

SELECT u.first_name, 
    COUNT(*) FILTER (WHERE r.user_id IS NULL) as cnt_not_contacted,
    AVG((r.user_id IS NOT NULL)::int) as avg_contacted
FROM users u
CROSS JOIN organization o
LEFT JOIN organization_rating r ON u.user_id = r.user_id AND o.org_id = r.organization_id
WHERE o.bt_id = 1 AND u.user_id <> 62
GROUP BY u.user_id
选择u.first\u name,
计数(*)过滤器(其中r.user\u id为空)作为未联系的cnt\u,
平均值((r.user\u id不为NULL)::int)作为平均值
来自用户u
交叉连接组织
在u.user\u id=r.user\u id和o.org\u id=r.organization\u id上左加入组织
其中o.bt_id=1和u.user_id 62
按u.user\u id分组

您需要使用外部联接,这样无论联系方式如何,都可以恢复所有组织。然后有一个case语句和aggregation,显示联系人和非联系人的数量,然后进行计算。触点值上的Null值表示没有触点,在进行数学运算时需要将其视为零记住内部连接仅在两个表上都存在时显示记录:如果没有触点,则不显示记录。因此,需要外部环境。
SELECT u.first_name, 
    COUNT(*) FILTER (WHERE r.user_id IS NULL) as cnt_not_contacted,
    AVG((r.user_id IS NOT NULL)::int) as avg_contacted
FROM users u
CROSS JOIN organization o
LEFT JOIN organization_rating r ON u.user_id = r.user_id AND o.org_id = r.organization_id
WHERE o.bt_id = 1 AND u.user_id <> 62
GROUP BY u.user_id