【问题标题】:Counting organizations which user has not contacted统计用户未联系的组织
【发布时间】:2021-03-12 14:03:37
【问题描述】:

我是 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
)

使用此架构,组织具有业务类型,在该业务类型中为也具有该业务类型的用户提供支持。给予此支持后,用户可以使用 organization_rating 对该组织进行评分。按照这个逻辑,我想执行一个查询,它给出了用户已联系评级的组织与用户仍需要评级的组织的百分比。例如,假设 user_id 1 为组织 1 评分,该组织与用户具有相同的业务类型。还有 9 个组织具有相同的业务类型,但用户尚未对这些组织进行评级。此查询将返回 10%。

我有以下查询来计算用户已经联系过的组织:

Select U.first_name, COUNT(R.rating)
From users as U INNER JOIN organization_rating as R on U.user_id = R.user_id
Inner join organization as O on O.org_id = R.organization_id
Where O.bt_id = 1 AND R.user_id != 62
Group by U.first_name;

我如何计算该用户尚未联系的组织,以及已联系与仍需联系的百分比?

如果您还可以向我推荐一些可以帮助我了解更多 PostgreSQL 和不同功能的网站,我将不胜感激。提前谢谢!

【问题讨论】:

  • 您需要使用外部联接,以便让所有组织恢复,而不管联系方式如何。然后有一个案例陈述和聚合,显示联系人数量与非联系人数量,然后进行数学计算。联系人值上的空值表示没有联系人,在进行数学运算时需要将其视为零 记住内部联接仅在两个表上都存在时才显示记录:如果不存在联系人,则不正确。因此需要外部。

标签: sql postgresql count left-join inner-join


【解决方案1】:

您可以cross join 的用途和组织获得所有可能的组合,然后带上带有left join 的桥接表。最后一步是条件聚合:

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

【讨论】:

    猜你喜欢
    • 2017-05-23
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2011-12-20
    • 1970-01-01
    相关资源
    最近更新 更多